1

benim mimarisinde Benim katmanları depo, iş ve bağımlılık enjeksiyon kalıplarının birimini kullanın:Depo Desen Birim Ninject

Çekirdek

dataLayer'ı

BusinessLayer

ServiceLayer

Yapım birimimde, iş sınıfı biriminde bir sorun var i _kullaniciDAL gibi DataAccessLayers enjekte etmek istiyorum burada

public class UnitOfWork:IUnitOfWork 
{ 
    private readonly IDataContext _context; 
    private IKullaniciDal _kullaniciDal; 
    private IKategoriDal _kategoriDal; 
    private IUrunDal _urunDal; 
    public UnitOfWork(IDataContext context) 
    { 
     _context = context; 
    } 

    public IKategoriDal KategoriDal => _kategoriDal ?? (_kategoriDal = new KategoriDal(_context)); 

    public IKullaniciDal KullaniciDal => _kullaniciDal ?? (_kullaniciDal = new KullaniciDal(_context)); 

    public IUrunDal UrunDal => _urunDal ?? (_urunDal = new UrunDal(_context)); 

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

yukarıdaki gibi

çok aranan ve ben iş doğrudan depo örneğine erişmek istemiyorum met depo genericly üretmek için bazı örnekler gördük, ben erişmek istediğiniz benim KullaniciDal sınıfının İşte örneklerinin KullaniciDal

kodu
public interface IKullaniciDal : IRepositoryEntityFramework<Kullanici> 
{ 
} 

public class KullaniciDal : RepositoryEntityFramework<Kullanici>, IKullaniciDal 
{ 
    public KullaniciDal(IDataContext dbContextBase) : base(dbContextBase) 
    { 
    } 
} 

Ben bazıları özel veri erişim katmanı bazı ekstra fonksiyonlar yazmak istiyorum gibi örneklerini kullanmak istemeniz iş sınıfı biriminin bir bölümü

Dal sınıflarını nasıl enjekte edebilirim? Bağlam nesnesini her dal sınıfına geçirdiğim konusunda dikkatli olun

cevap

1

Burada gördüğüm birkaç sorun var.

İlk olarak, UoW'nuz DI tarafından enjekte edilmek yerine DAL'in kendisini yenilemektedir. Eğer DI rotasına gidiyorsanız, DI'nin her şeyi enjekte etmesine izin verin ve nesnelerin kapsamını kendi başına yönetmesine izin verin. Genel bir kural olarak, kendinizi bir altyapı sınıfıyla yeni() kullanarak bulursanız, bir adım geri atın ve enjekte etmeyi düşünün.

public class UnitOfWork:IUnitOfWork 
{ 
    private readonly IDataContext _context; 
    public UnitOfWork(IDataContext context,IKullaniciDal kullaniciDal,IKategoriDal kategoriDal, IUrunDal urunDal) 
    { 
     KullaniciDal = kullaniciDal; 
     KategoriDal = kategoriDal; 
     UrunDal = urunDal; 
     _context = context; 
    } 

    public IKategoriDal KategoriDal{get;private set;} 

    public IKullaniciDal KullaniciDal{get;private set;} 

    public IUrunDal UrunDal{get;private set;} 

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

Bir sonraki soru bir tasarım sorusudur. Neden tüm bu DAL'lar UoW ​​tarafından gerekli? Kendimi tuhaf buluyorum.

UoW ve DAL'yi kontrol etmesi gereken bir iş katmanı uyguluyor olsaydım, bunları basitçe iş katmanına enjekte ederdim.

public class FooBLL 
{ 
    private IKullanicDal _kullanicDal; 
    private IUnitOfWork _unitOfWork; 
    public FooBLL(IKullanicDal kullanicDal,IUnitOfWork unitOfWork) 
    { 
     _kullanicDal = kullanicDal; 
     _unitOfWork = unitOfWork; 
    } 

    public void FooBusinessMethod() 
    { 
     _unitOfWork.Begin(); 
     //do something with dal 
     //_unitOfWork.Commit etc 
    } 

} 

Bu Bağlam böyle EF olarak bir ORM kullanırken depo/dll ve iş birimi hem gerektirdiği, ancak ayrı desenler vardır ki doğrudur. DI konteynerinizin hem içeriğinizi, UoW'unuzu, hem de BLL'inizi uygun bir şekilde kapsamalarına izin veririm ve bağımlılıkların etrafından geçme konusunda endişelenmenize gerek kalmaz, konteynerin işi sizin için yapmasına izin verin.

Bu, diğer SOLID tasarım avantajlarına da sahiptir. Uyguladığınız takdirde, http oturumunu otomatik olarak işleyen bir http filtresi olduğunu düşünün. Filtrenin sadece IUnitOfWork yöntemlerini bilmesi, geri alması vb. Hakkında bilmesi gerekir. Bu minimum arayüze bağlı olmalı, DAL'leri bilmesi gerekmez.

+0

Sunulan gibi denedim ama çalışma birimindeki bağlam örneğinin ve daldaki örneğin aynı olmadığı konusunda bir sorunum var. ninject Bind () kullanıyorum. (). InRequestScope(); nerede yanlış yapıyorum –

+0

@OkanSARICA Bu, reddetme yapılandırmanızda bir kapsam belirleme sorunu olmalı, lütfen bu kodu da gönderin. – Brook

+0

Ninject.Web.Common nuget paketini kullanıyordum, onu kaldırdım ve Ninject.Mvc3'ü kurdum ve problem çözüldü, ilginç –

0

İhtiyaç duyulduğunda anında depo oluşturmak için başka bir çözüm buldum. Ayrıca, yanıltıcı veri bağlamlarını destekler ve IUnitOfWork arabiriminin IDT'leri devrettiği bir nokta daha vardır. Kod, EF Çekirdek v2.0 içindir. İşte tüm UnitOfWork.cs sınıf kodu:

public class UnitOfWork<TContext> : IUnitOfWork<TContext> where TContext : DbContext 
{ 
    private Dictionary<string, dynamic> _repositories; 
    private DbContext _context; 

    public UnitOfWork(TContext context) 
    { 
     _context = context ?? throw new ArgumentNullException(nameof(context)); 
    } 

    public IRepository<TEntity> Repository<TEntity>() where TEntity : class, IEntity, new() 
    { 
     if (_repositories == null) 
     { 
      _repositories = new Dictionary<string, dynamic>(); 
     } 
     var type = typeof(TEntity).Name; 
     if (_repositories.ContainsKey(type)) 
     { 
      return (IRepository<TEntity>)_repositories[type]; 
     } 
     _repositories.Add(type, Activator.CreateInstance(typeof(RepositoryEntityFramework<TEntity>), _context)); 
     return _repositories[type]; 
    } 

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

    public void BeginTransaction(System.Data.IsolationLevel isolationLevel = System.Data.IsolationLevel.ReadCommitted) 
    { 
     _context.Database.BeginTransaction(); 
    } 

    public bool Commit() 
    { 
     _context.Database.CommitTransaction(); 
     return true; 
    } 

    public void Rollback() 
    { 
     _context.Database.RollbackTransaction(); 
    } 

    /// <inheritdoc /> 
    /// <summary> 
    /// Disposes the current object 
    /// </summary> 
    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    /// <summary> 
    /// Disposes all external resources. 
    /// </summary> 
    /// <param name="disposing">The dispose indicator.</param> 
    private void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      if (_context != null) 
      { 
       _context.Dispose(); 
       _context = null; 
      } 
     } 
    } 
}