2015-03-11 2 views
1

Как настроить AutoFac, чтобы каждый раз, когда я попадал на завод, я получал новый экземпляр Context. Компонент Content настроен на InstancePerLifetimeScope(), что идеально подходит для 99% моего использования, но теперь мне нужно немного дополнительного контроля над тем, как компонент Context находится в зоне действия.Переопределение конфигурации области AutoFac при использовании фабрики

class Program 
{ 
    static void Main(string[] args) 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterType<Box>(); 
     builder.RegisterType<DbContext>().InstancePerLifetimeScope(); 

     var container = builder.Build(); 

     using (var scope = container.BeginLifetimeScope()) 
     { 
      var x = scope.Resolve<Box>(); 
     } 

     Console.ReadKey(); 
    } 
} 

class Box 
{ 
    public Box(DbContext.Factory factory) 
    { 
     factory(); 
     factory(); // Want this to generate a NEW instance 

     Console.WriteLine("Box: {0}", GetHashCode()); 
    } 
} 

class DbContext 
{ 
    public delegate DbContext Factory(); 

    public DbContext() 
    { 
     Console.WriteLine("Context: {0}", GetHashCode()); 
    } 
} 

Очевидно, что это довольно упрощенный фрагмент кода. Проблема, которую я пытаюсь решить, заключается в том, что у меня огромный поток данных, поступающих в службу, и я пытаюсь сохранить пакет в базу данных. Итак, если Box может создавать новые UOW по запросу и своевременно выпускать их для утилизации, тогда я получаю хорошее чистое решение.

Спасибо!

ответ

3

Вы можете использовать Func<Owned<>>, который работает как маленький ILifetimeScope:

public Box(Func<Owned<DbContext>> factory) 
{ 
    using (Owned<DbContext> ownedDbContext = factory()) 
    { 
     // instance1 
    } 
    using (Owned<DbContext> ownedDbContext = factory()) 
    { 
     // instance2 
    } 
} 

Вы можете найти более подробную информацию о документации Autofac: Owned Instances

Другим решением является впрыснуть ILifetimeScope, а затем создать вложенную lifetimescope:

public Box(ILifetimeScope scope) 
{ 
    using (ILifetimeScope subScope = scope.BeginLifetimeScope()) 
    { 
     DbContext dbContext = subScope.Resolve<DbContext>(); 
    } 
} 

или

public Box(ILifetimeScope scope) 
{ 
    ILifetimeScope subScope = scope.BeginLifetimeScope(); 
    scope.Disposer.AddInstanceForDisposal(subScope); 
    DbContext dbContext = subScope.Resolve<DbContext>(); 
    // no need to dispose subScope, 
    // subScope (and dbContext) will be disposed at the same time as scope 
} 
+0

Да. Я пришел к тому же решению. Хороший. – MJM

Смежные вопросы