ben yeni servisi
eklemek istedikleri zaman UOW kodu dokunmak zorunda kalmazsınız böylece benim hizmetler veya deposundan işin Birimimi ayrıştırmak çalışıyorum
Eh, bu iyi bir başlangıç! ;-)
Sunmakta olduğum çözüm tek ve olası çözüm değil, UoW'yi uygulamak için birkaç iyi yol var (Google size yardımcı olacak). Ama bu sana büyük resmi vermeli. IUnitOfWork ve IRepository
public interface IUnitOfWork : System.IDisposable
{
IRepository<TEntity> GetRepository<TEntity>() where TEntity : class;
void Save();
}
public interface IRepository<T> : IDisposable where T : class
{
void Add(T entity);
void Delete(T entity);
void Update(T entity);
T GetById(long Id);
IEnumerable<T> All();
IEnumerable<T> AllReadOnly();
IEnumerable<T> Find(Expression<Func<T, bool>> predicate);
}
uygulamaları oldukça basittir (ı okunabilirliği amacıyla tüm yorumlarımı kaldırdık, ancak ;-) sizindir eklemeyi unutmayın)
public class UnitOfWork<TContext> : IUnitOfWork where TContext : IDbContext, new()
{
private readonly IDbContext _ctx;
private Dictionary<Type, object> _repositories;
private bool _disposed;
public UnitOfWork()
{
_ctx = new TContext();
_repositories = new Dictionary<Type, object>();
_disposed = false;
}
public IRepository<TEntity> GetRepository<TEntity>() where TEntity : class
{
if (_repositories.Keys.Contains(typeof(TEntity)))
return _repositories[typeof(TEntity)] as IRepository<TEntity>;
var repository = new Repository<TEntity>(_ctx);
_repositories.Add(typeof(TEntity), repository);
return repository;
}
public void Save()
{
try
{
_ctx.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
ex.Entries.First().Reload();
}
}
…
}
public class Repository<T> : IRepository<T> where T : class
{
private readonly IDbContext _context;
private readonly IDbSet<T> _dbset;
public Repository(IDbContext context)
{
_context = context;
_dbset = context.Set<T>();
}
public virtual void Add(T entity)
{
_dbset.Add(entity);
}
public virtual void Delete(T entity)
{
var entry = _context.Entry(entity);
entry.State = EntityState.Deleted;
}
public virtual void Update(T entity)
{
var entry = _context.Entry(entity);
_dbset.Attach(entity);
entry.State = EntityState.Modified;
}
public virtual T GetById(long id)
{
return _dbset.Find(id);
}
public virtual IEnumerable<T> All()
{
return _dbset.ToList();
}
public virtual IEnumerable<T> AllReadOnly()
{
return _dbset.AsNoTracking().ToList();
}
public IEnumerable<T> Find(Expression<Func<T, bool>> predicate)
{
return _dbset.Where(predicate);
}
}
:
Öncelikle 2 arayüzleri yaratmak
Gördüğünüz gibi, her iki uygulama da IDbContext arabirimini kullanır.
public interface IDbContext
{
DbSet<T> Set<T>() where T : class;
DbEntityEntry<T> Entry<T>(T entity) where T : class;
int SaveChanges();
void Dispose();
}
(Gördüğünüz gibi, ben kullanıyorum EntityFramework Kod İlk) Şimdi bütün sıhhi tesisat şekilde ayarlandığını
, aşağıdakiler bu bir göz atalım: Bu arayüz sadece kolay test amaçlıdır bir serviste kullanılabilir. Şöyle bir baz hizmeti:
internal class Service<T> where T : class
{
internal Service(Infrastructure.IUnitOfWork uow)
{
_repository = uow.GetRepository<T>();
}
protected Infrastructure.IRepository<T> Repository
{
get { return _repository; }
}
private readonly Infrastructure.IRepository<T> _repository;
}
Ve tüm hizmetlerim bu taban hizmetinden devralır.
internal class CustomerService : Service<Model.Customer>
{
internal CustomerService(Infrastructure.IUnitOfWork uow) : base(uow)
{
}
internal void Add(Model.Customer customer)
{
Repository.Add(customer);
}
internal Model.Customer GetByID(int id)
{
return Repository.Find(c => c.CustomerId == id);
}
}
Ve işte bu! Eğer bir cephe yöntemiyle veya başka bir yere de birkaç hizmetlerine aynı UOW paylaşmak istiyorsanız
Şimdi, sadece bu gibi görünebilir:
using (var uow = new UnitOfWork<CompanyContext>())
{
var catService = new Services.CategoryService(uow);
var custService = new Services.CustomerService(uow);
var cat = new Model.Category { Name = catName };
catService.Add(dep);
custService.Add(new Model.Customer { Name = custName, Category = cat });
uow.Save();
}
Umut bu yardımcı olur!
Senaryonuz hakkında daha fazla bilgi verebilir misiniz? Bana bağımlılık enjeksiyonundan bahsediyorsunuz (kodunuz ICategoryService'ye bağlıdır ve otomatik olarak enjekte etmek istersiniz), fakat sorunuzdan belli değildir. –
Merhaba! UoW modelini incelemek için bir MVC4 test projem var. Bir denetleyicim, depoya başvuran bir hizmet sınıfım var. Ama gördüğünüz gibi UoW'mda bir Category olarak bu Kategori Hizmetim var. Sonra, gelecekte bir şey için yeni bir hizmet oluşturduğumda, bu hizmeti sahip olduğum UoW sınıfına eklemem gerektiğini anladım.Sadece hangi arabirime geçtiğime bağlı olarak bir hizmet türü döndüren Get işlevine sahip olmanın bir yolunu bulmaya çalışıyorum. Bunun bunun için doğru yol olup olmadığından emin değilim. Teşekkürler! –
UoW kabı için ne kullanıyorsunuz? Bazı IoC'leri kullanmalı, güzel bir liste için bu sayfayı kontrol etmelisiniz: http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx Çoğu,() yöntemini veya benzerini çözer ve bunları asp.net mvc'de varsayılan bağımlılık çözümleyici olarak kullanırsınız, böylece denetleyicinize sadece IService parametresini eklersiniz. Bu ne soruyorsun? –