私は新しいサービス
を追加し を希望するたびUOWコードに触れていないように私のサービスや リポジトリから作業の私のユニットを分離しようとしています
さて、それは良いスタートです! ;-)
私が提示している解決策は、唯一可能な解決策ではありません.UoWを実装するいくつかの良い方法があります(Googleがお手伝いします)。しかし、これはあなたに大きなイメージを与えるはずです。 IUnitOfWorkと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);
}
実装は非常に簡単です(私は読みやすさの目的のためにすべての私のコメントを削除しますが、;-)あなた追加することを忘れないでください)
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);
}
}
:
まず、2つのインターフェースを作成
ご覧のとおり、どちらの実装もIDbContextインターフェイスを使用しています。
public interface IDbContext
{
DbSet<T> Set<T>() where T : class;
DbEntityEntry<T> Entry<T>(T entity) where T : class;
int SaveChanges();
void Dispose();
}
(あなたが見ることができるように、私が使用しているEntityFrameworkコードファースト)さて、全体の配管が設定されていることを
、のは、どのようにこれを見てみましょう:このインタフェースは、単に簡単にテストするためのものでありサービスで使用することができます。 私はこのようになりますベースのサービスがあります。
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;
}
そして、すべての私のサービスは、この基本サービスを継承します。
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);
}
}
それだけです!あなたはファサードメソッドまたはどこか他の場所で、複数のサービスに同じUOWを共有したい場合は
今、それだけで次のようになります。
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();
}
ホープ、このことができます!
あなたのシナリオについてもっと詳しく説明できますか?依存関係の注入(あなたのコードはICategoryServiceに依存し、自動的に注入したいと思っています)について話しているようですが、あなたの質問からは明らかではありません。 –
こんにちは! UoWパターンを学習するためのMVC4テストプロジェクトがあります。私はコントローラ、リポジトリを参照するサービスクラスを持っています。しかし、あなたが見ることができるように、私はこのCategoryServiceを私のUoWにプロパティとして持っています。それから私は将来、何かのために新しいサービスを作るたびに、私が持っているUoWクラスにこのサービスを追加しなければならないことに気付きました。私はそれに渡されたインターフェイスに基づいてサービスタイプを返すGet関数を持つ方法を見つけることを試みています。それが正しいかどうかは確かではありません。ありがとう! –
UoWコンテナには何を使用していますか?あなたはいくつかのIoCを使うべきです、このページで良いリストをチェックしてください:http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspxそれらのほとんどは.Resolve()メソッドを持っています。それらをasp.net mvcのデフォルト依存リゾルバとして使用するので、コントローラにパラメータとしてIServiceを追加するだけです。あなたは何を求めているのですか? –