В настоящее время я настраиваю новое веб-приложение MVC, используя внедрение зависимостей (autofac).Я действительно знал, что такое инъекция зависимостей, поэтому я чувствую, что мне чего-то не хватает.У меня есть рабочее решение (опубликовано ниже), но я чувствую, что мое решение идет вразрез с тем, что пытается сделать Autofac, путем разрешения зависимостей.
По сути, у меня есть служба, эта служба имеет несколько UnitOfWork, каждыйUnitOfWork имеет несколько репозиториев, и они совместно используют один экземпляр dbcontext (принадлежит UnitOfWork).Мне нужно, чтобы IDatabaseFactory создавался для передачи UnitOfWork в репозиторий.Это сделано для того, чтобы хранилище не могло утилизировать контекст, который используется другим хранилищем в экземпляре singleUnitOfWork.
Это то, что я пробовал.
Упрощенный макет службы
public class NewsletterService :INewsletterService
{
TestUnitOfWork _uow1;
TestUnitofWork2 _uow2;
public NewsletterService(TestUnitOfWork uow, TestUnitOfWork2 uow2 )
{
_uow1 = uow;
_uow2 = uow2;
}
}
Простая реализованная единица работы (интерфейсы, основанные на примерах из msdn) Я оставил интерфейс вне, он просто делает вещи, которые не имеют отношения к проблеме (мы не можем пройти мимо конструкции).ContactSubscription - это просто модель.
public class TestUnitOfWork : UowBase, IUnitOfWork
{
public TestUnitOfWork(IDatabaseFactory factory,
GenericRepository<ContactSubscription> repo)
: base(factory)
{
}
}
Общий репо
public class GenericRepository <TEntity> : IRepository<TEntity> where TEntity : class
{
private readonly ApplicationDbContext _context;
private readonly DbSet<TEntity> _dbSet;
public GenericRepository(IDatabaseFactory factory)
{
_context = factory.Get();
_dbSet = _context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
// ...
}
}
Реализация базы данных фабрики
public class UniqueDatabaseFactory : IDatabaseFactory
{
private ApplicationDbContext _context;
public Guid guid = Guid.NewGuid(); // using guid to quickly check instances.
public ApplicationDbContext Get()
{
return _context ?? ( _context = ApplicationDbContext.Create());
}
}
и регистрация выглядит следующим образом:
builder.RegisterType<NewsletterService>()
.As<INewsletterService>()
.InstancePerRequest();
builder.RegisterGeneric(typeof(GenericRepository<>))
.AsSelf()
.As(typeof(IRepository<>))
.InstancePerLifetimeScope();
builder.RegisterType<TestUnitOfWork>().AsSelf().InstancePerRequest();
builder.RegisterType<TestUnitOfWork2>().AsSelf().InstancePerRequest();
builder.RegisterType<UniqueDatabaseFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope();
Мои результаты до сих пор При использовании UnitOfWork в качестве InstancePerRequest мы получаем хорошие, но не очень хорошие результаты.IDatabaseContext используется всеми экземплярами UnitOfWork для службы-владельца.Кажется, что другие методы регистрации с autofac создают новый экземпляр IDatabaseFactory для каждого использования, например.использование InstancesPerLifetimeScope при регистрации.
Рабочее (но не правильное) решение
В качестве альтернативы этот метод сработал, но, будучи новичком в внедрении Dependency, кажется, что я иду противто, что пытается сделать Autofac, разрешая зависимости.
builder.Register(c =>
{
IDatabaseFactory factory = c.Resolve<IDatabaseFactory>();
GenericRepository<ContactSubscription> repo = c.Resolve<GenericRepository<ContactSubscription>>(
new NamedParameter("factory", (object)factory));
return new TestUnitOfWork(factory, repo);
}).AsSelf().InstancePerLifetimeScope();
Я сильно чувствую, что приведенное выше решение не является идеальным (с небольшими знаниями, которые у меня есть с контейнерами loc), и вместо того, чтобы причинять себе больше головной болиВ дальнейшем я хочу посмотреть, есть ли более эффективный способ иметь IDatabaseFactory, которая создается Autofac для UnitOfWork, чтобы передавать те же экземпляры в хранилище, но не сохранять тот же экземпляр для других UnitOfWork.
Мой проект сейчас беспорядок, так что, надеюсь, в коде примера нет опечаток или старых переменных, которые я пропустил.Спасибо!