2014-09-28 7 views
5

के साथ रिपोजिटरी और वर्क पैटर्न के यूनिट का सर्वोत्तम अभ्यास मैं एंटिटी फ्रेमवर्क 6 (कोड फर्स्ट/पीओसीओ) के साथ एएसपी.नेट एमवीसी का उपयोग कर एक वेब एप्लिकेशन विकसित करने की योजना बना रहा हूं। मैं अपने आवेदन में जेनेरिक रिपोजिटरी और वर्क पैटर्न का यूनिट भी उपयोग करना चाहता हूं। यह एप्लिकेशन दो से अधिक डेटाबेस से जुड़ता है, इसलिए मुझे एप्लिकेशन में एकाधिक डीबीकॉन्टेक्स्ट का उपयोग करना होगा।एकाधिक डीबीकॉन्टेक्स्ट

public class ContextOne : DbContext 
{ 
    public DbSet<Model_One1> 
    public DbSet<Model_One2> 
} 

public class ContextTwo : DbContext 
{ 
    public DbSet<Model_Two1> 
    public DbSet<Model_Two2> 
} 

public class ContextThree : DbContext 
{ 
    public DbSet<Model_Three1> 
    public DbSet<Model_Three2> 
} 

public interface IRepository<T> where T : DbContext 
{ 
    void Add<T>(T entity) where T : class; 
} 

public class Repository<T> where T : DbContext 
{ 
    void Add<T>(T entity) where T : class 
    { 
     //T is DbContext and Model. So confusing 
    } 
} 

public interface IUnitOfWork<IRepository> 
{ 
} 

public class UnitOfWork<IRepository> 
{ 
    //IRepository contains more than one DbContext how can I initiate them here? 
} 

//in application should look like this 
public class BaseController : Controller 
{ 
    protected IRepository repository = new .. //here I have no idea with multiple DbContext 
} 

public class HomeController : BaseController 
{ 
    public ActionResult Add(Model_Two2 model) 
    { 
     base.repository.Add<Model_Two2>(model) 
    } 
} 

अगर मैं IRepository और IUnitOfWork नियंत्रक से फोन कैसे मैं मिलान संदर्भ पता कर सकते हैं? इस समस्या का सबसे अच्छा अभ्यास क्या है?

उत्तर

6

मैं DbContext स्वीकार करने के लिए एक निर्माता पैरामीटर के साथ UnitOfWork पैटर्न बनाने के लिए सुझाव है -

public class UnitOfWork : IUnitOfWork 
{ 
    private readonly IDbContext _context; 

    private bool _disposed; 
    private Hashtable _repositories; 

    public UnitOfWork(IDbContext context) 
    { 
     _context = context; 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    public void Save() 
    { 
     _context.SaveChanges(); 
    } 

    public virtual void Dispose(bool disposing) 
    { 
     if (!_disposed) 
      if (disposing) 
       _context.Dispose(); 

     _disposed = true; 
    } 

    public IRepository<TEntity> Repository<TEntity>() where TEntity : class 
    { 
     if (_repositories == null) 
      _repositories = new Hashtable(); 

     var type = typeof(TEntity).Name; 

     if (_repositories.ContainsKey(type)) return (IRepository<TEntity>) _repositories[type]; 

     var repositoryType = typeof (Repository<>); 

     var repositoryInstance = 
      Activator.CreateInstance(repositoryType 
       .MakeGenericType(typeof (TEntity)), _context); 

     _repositories.Add(type, repositoryInstance); 

     return (IRepository<TEntity>) _repositories[type]; 
    } 
} 

जहां IDbContext है -

public interface IDbContext 
{ 
    IDbSet<T> Set<T>() where T : class; 
    int SaveChanges(); 
    void Dispose(); 
} 

और भंडार कार्यान्वयन होगा -

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class 
    { 
     internal IDbContext Context; 
     internal IDbSet<TEntity> DbSet; 

     public Repository(IDbContext context) 
     { 
      Context = context; 
      DbSet = context.Set<TEntity>(); 
     } 

     public virtual TEntity FindById(object id) 
     { 
      return DbSet.Find(id); 
     } 

     public virtual void Update(TEntity entity) 
     { 
      DbSet.Attach(entity); 
     } 
     public virtual void Delete(object id) 
     { 
      var entity = DbSet.Find(id); 
      var objectState = entity as IObjectState; 
      if (objectState != null) 
       objectState.State = ObjectState.Deleted; 
      Delete(entity); 
     } 

     public virtual void Delete(TEntity entity) 
     { 
      DbSet.Attach(entity); 
      DbSet.Remove(entity); 
     } 

     public virtual void Insert(TEntity entity) 
     { 
      DbSet.Attach(entity); 
     } 

     public virtual List<TEntity> GetAll() 
     { 
      return DbSet.ToList(); 
     } 
    } 

इस दृष्टिकोण के साथ आप व्यक्तिगत डीबीसीएन्टेक्स्ट के लिए यूनिटऑफवर्क बना सकते हैं और आपके पास UnitOfWork में प्रतिबद्ध या रोलबैक के लिए विशिष्ट तर्क है।

+0

मुझे अपने बेसकंट्रोलर में आईआरपॉजिटरी और IUnitOfWork को कैसे कॉल करना चाहिए? क्या मुझे प्रत्येक मॉडल के लिए सैकड़ों आईरिपोजिटरी इंस्टेंस बनाना चाहिए? उदाहरण के लिए, 'आईरिपोजिटरी रिपोजिटरी स्टूडेंट = नया रिपोजिटरी () 'आदि, आदि – derodevil

+0

मुझे नहीं लगता कि' बेसकंट्रोलर 'यूओडब्ल्यू शुरू करने के लिए सही जगह होगी। इसके बजाय इसे आपके व्यावसायिक प्रक्रिया स्तर पर मांग के आधार पर बनाया जाना चाहिए। तो आवश्यक आधार के अनुसार डीबी कॉन्टैक्स से बाहर विशिष्ट यूओडब्ल्यू बनाएं और फिर विशिष्ट भंडार प्राप्त करें। – ramiramilu

+0

चूंकि आपके 'यूनिटऑफवर्क' में विनाशक और अप्रबंधित संसाधन नहीं हैं, इसलिए आपको 'GC.SuppressFinalize (this) 'को कॉल करने की आवश्यकता नहीं है और निपटान पैटर्न को लागू करने की आवश्यकता नहीं है। आपको 'Unitconfork.Dispose' में केवल' _context.Dispose() 'को कॉल करने की आवश्यकता है – Albert

0

मैं UnitOfWork एक ActionAttribute जहां OnActionExecuting मैं लेन-देन को खोलने के रूप में, और OnActionExecuted लागू करेगा मैं, अगर सब कुछ ठीक है लेन-देन के लिए प्रतिबद्ध अगर वहाँ ActionContext में अपवाद नहीं है, लेन-देन वापस लुढ़का किया जाना चाहिए।

मुश्किल बात यह है कि आपके पास 2 डीबीकॉन्टेक्स हैं। मुझे लगता है, आपको dbContexts की आलसी सृजन होना चाहिए। UnitOfWork.OnActionExecuting में इसे True पर सेट करें और इसे True पर सेट करें। फिर, जब आप पहली बार dbContext को स्पर्श करते हैं, तो आपको यह जांचना चाहिए कि क्या आप UnitOfWork से निपट रहे हैं, और यदि हां, तो आपको इस विशेष dbContext के लिए लेनदेन खोलना चाहिए। सभी खुले लेनदेन को एक सूची में रखा जा सकता है जो UnitOfWork.ActionExecuted से सुलभ है। अंत में, जांचें कि क्या ActionContext में कोई अपवाद हैं: हाँ - Rollback, नहीं - Commit

+0

Commit और रोलबैक लेनदेन के लिए कोई समस्या नहीं है। मुझे कई डीबीकॉन्टेक्स्ट के साथ रेस्पिटरी और यूओडब्लू पैटर्न बनाने के लिए सर्वोत्तम अभ्यास के बारे में स्पष्टीकरण की आवश्यकता है क्योंकि मेरे एप्लिकेशन को एक ही और विभिन्न सर्वरों पर एकाधिक डेटाबेस से कनेक्ट करना है। मैं एक सामान्य यूओडब्ल्यू चाहता हूं जिसमें एकल जेनेरिक रिपोजिटरी इन डीबी कॉन्टैक्स को संभाल सके। – derodevil

संबंधित मुद्दे