2016-03-02 3 views
0

У меня есть консольное приложение - рабочий - который прослушивает сообщения, входящие в систему quering, и выполняет некоторые задачи, связанные с доступом к базе данных для каждого из сообщений. Я использую EF 6 для доступа к db MSSQL, и в моей реализации я использую Единицу работы. Мой контейнер DI Autofac - я новичок в этом, и я использую его для связывания между многими другими функциями IUnitOfWork для UnitOfWork.Autofac, консольное приложение и UnitOfWork

Проблема, с которой я столкнулся, и я не знаю, как с этим бороться: я хочу, чтобы каждый экземпляр UnitOFWork для каждого сообщения, поэтому он не может быть Singleton, но во время той же обработки сообщений мне нужен тот же экземпляр UnitOfWork, поэтому он не может быть -Instance Per Dependency.

спасибо.

ответ

1

Вы должны зарегистрировать его в качестве Instance Per Lifetime Scope

Когда приходит сообщение, вы должны начать новый пожизненный Scope и устранить IUnitOFWork там. Таким образом у вас будет 1 UnitOFWork объект в этом lifetimescope.

Ваш регистр должен быть такой:

builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope(); 

И вы должны решить IUnitOfWork так:

var message=GetMessageFromBus(); 
using(var myLifetime = container.BeginLifetimeScope()) 
{ 
    var myUnitOFWork = myLifetime.Resolve<IUnitOfWork>(); 
} 
2

В качестве альтернативы использования контейнера непосредственно, как показано на @ MaDeRkAn Ответит вы также можете использовать Func<Owned<IUnitOfWork>> вместо:

containerBuilder 
    .RegisterType<UnitOfWork>() 
    .As<IUnitOfWork>() 
    .InstancePerLifetimeScope(); 

public class MessageQueueWorker 
{ 
    private Func<Owned<IUnitOfWork>> unitOfWorkFactory; 

    public MessageQueueWorker(Func<Owned<IUnitOfWork>> unitOfWorkFactory) 
    { 
     this.unitOfWorkFactory = unitOfWorkFactory 
    } 

    public void ProcessMessage(message) 
    { 
     using (Owned<IUnitOfWork> unitOfWork = this.unitOfWorkFactory()) 
     { 
      //access the actual IUnitOfWork with the .Value property 
      unitOfWork.Value.DatabaseTable.... 

      // when the using scope ends the IUnitOfWork and all it's 
      // "non shared" dependencies will be disposed 
     } 
    } 
} 

Подсказка: относительно «не общих» зависимостей: это те, которые имеют тот же или более короткий масштаб, чем IUnitOfWork. А SingleInstance, введенный в IunitOfWork, не будет утилизирован, конечно.

+0

Это лучшее решение. В частности, если вы не можете добраться до контейнера, как проекты промежуточного программного обеспечения. –

+2

@MaDeRkAn 'ILifetimeScope' и' Owned' оба определены в сборке 'Autofac', поэтому я предполагаю, что у одного есть либо доступ к обоим, либо none. Мне нравится использовать 'Owned' больше, потому что я думаю, что идея выражена более« лаконично и точно ». Это всегда можно написать для него обычную оболочку, хотя - если вы хотите убедиться, что не слишком много материалов «Составной корень» просачивается во все проекты. – BatteryBackupUnit