MEF implements "loose coupling" in design

Source: Internet
Author: User
Tags to domain

Preface: The previous C # Advanced series--mef realizes the design of "loose coupling" (a) introduces the basic usage of the lower MEF, let us have an abstract understanding of the MEF. Of course, the use of MEF may not be limited to this, such as MEF directory services, directory filtering, reorganization parts and other advanced applications here do not do too much to explain, because bloggers think that these usages only under certain circumstances will be used, it is not very common, feel the need to drill down. If you are interested, you can get to know it. This article intends to combine the MEF and warehousing models to talk about the use of MEF in projects.

1, storage mode: Also known as repository mode. Repository is a separate layer, between the domain layer and the Data map layer (the data access layer). Its existence makes the domain layer feel the presence of the data access layer, which provides a similar set of interfaces that provide access to domain objects for domain layers. Repository is the warehouse manager, the domain layer needs to tell the warehouse manager, the warehouse manager to bring things to it, do not need to know where things are actually put. Repository mode is generally used to encapsulate the data access layer, which is why many places see what is said about "data warehousing", which is probably the meaning. Repository mode is not the focus of this article, it is no longer open, and will share this piece separately.

There are several points to note about the warehousing model:

(1) The repository mode is the architecture mode, which has the reference value when designing the architecture;

(2) The significance of repository mode use: First, the isolation of the business logic layer and the underlying data access layer to ensure the uniqueness of the data entry, and the second is that the repository pattern is designed for the aggregation root, not for tables and entities, in other words, The use of repository is to achieve cohesion, the front-end is only responsible for the repository request data, and do not care about the specific source of data;

(3) Repository mode actual use: Replace, upgrade ORM engine, do not affect the business logic;

The above stuff is a bit of an official writing. Bo Master's understanding is that the storage model is to the data access layer (or called the Data Map layer) to do a layer of packaging, each time the front-end needs to query what data or submit what data, are through the storage object repository to operate, the front-end basically do not feel the existence of the data access layer. Does that mean you have a good understanding? No? OK, let's see the demo.

2, MEF in the storage mode above the application: Because the framework uses the EF, so it is also used in conjunction with the EF warehousing model. In order to omit the complex structure of the repository pattern, we only use the storage Save method to illustrate.

Irepository<tentity> interface and Implementation code:

public interface irepository<t>     where t:baseentity    {        t Save (t entitiy);    }
[Export (typeof (Irepository<baseentity>))]    Public abstract class Repository<t>: irepository<t> where t:baseentity    {        //unit of work        [Import]        protected Iunitofwork Context {set; get;}        Private idbset<t> _entities;        Register MEF Public        Repository ()        {            register.regisgter (). Composeparts (this);        }        Public virtual T Save (t entitiy)        {            if (entitiy = = null) throw new ArgumentException ("entitiy nul");            Context. Save<t> (entitiy);            return entitiy;        }    }    public static class Register    {public        static Compositioncontainer Regisgter ()        {            var catalog = new Assemblycatalog (assembly.getexecutingassembly ());            var container = new Compositioncontainer (catalog);            return container;        }    }

BaseEntity is a common base class for an EF entity that defines the constraints that EF entities must follow.

Iunitofwork work cell interface and implementation

Public interface iunitofwork:idisposable    {        int Commit ();        void Rollback ();        void save<t> (T entity) where t:baseentity;    }
<summary>///Unit operation implementation///</summary>
[Export (typeof (Iunitofwork))] public abstract class Unitofworkcontextbase:iunitofwork {[Import Many] protected abstract ienumerable<dbcontext> contexts {get;} Protected abstract DbContext Cur_context {get; set;} Public Unitofworkcontextbase () {
          Register.regisgter (). Composeparts (this); if (Contexts.count () <= 0) {throw new Exception (); } Cur_context = Contexts.firstordefault (); }///<summary>//Gets whether the current unit operation has been committed///</summary> public bool iscommitted {get; private set;} <summary>///Submit results of current unit operations///</summary>//<returns></retu rns> public int Commit () {if (iscommitted) {RE Turn 0; } try {int result = Cur_context. SaveChanges (); Iscommitted = true; return result; } catch (Dbupdateexception e) {if (e.innerexception! = null && E . Innerexception.innErexception is SqlException) {SqlException Sqlex = e.innerexception.innerexcept Ion as SqlException; String msg = Datahelper.getsqlexceptionmessage (sqlex.number); Throw Publichelper.throwdataaccessexception ("exception occurred while submitting data update:" + MSG, Sqlex); } throw; }}///<summary>//Roll back the current unit operation to uncommitted status///</summary> PU Blic void Rollback () {iscommitted = false; } public void Dispose () {if (! iscommitted) {Commit (); } cur_context. Dispose (); The public void save<t> (T entity) where T:t {cur_context. SaveChanges (); } }

Since ImportMany is used here, there must be a place for export. We use EF to create a new edmx file that adds an export to the generated context object

[Export (typeof (DbContext))]    public partial class Entities:dbcontext    {public        entities ()            : Base ("Name=entities")        {        }            protected override void Onmodelcreating (Dbmodelbuilder modelBuilder)        {            throw new Unintentionalcodefirstexception ();        }            Public dbset<tb_users> tb_users {get; set;}    }

Why do you use ImportMany here? As stated earlier, one of the benefits of warehousing is to encapsulate the data access layer so that the front end is no more than a specific source of care data. When we build an EDMX for a database connection, we only need to modify the assignment of the Cur_context object in the repository, and since the other places are doing things for the context object of Cur_context, there is basically no need to make a big change. Around such a big circle, in fact, Bo Master just want to explain the import and ImportMany and warehousing model combined with the benefits, as for the applicability of warehousing model is not the focus of this article.

MEF implements "loose coupling" in design

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.