2015-12-28 2 views
2

С возможностью Unity можно разрешить до сборки контейнера. Возможно ли это с Autofac? Ниже код демонстрирует мой сценарий - мне нужно будет решить ICacheRepository, чтобы «обновить» синглтон CacheHelper.Autofac - разрешить перед сборкой

В единстве, которое было бы просто сделано с container.Resolve<ICacheRepository>() вместо ???. Как насчет Autofac?

var builder = new ContainerBuilder(); 
builder.RegisterType<CacheRepository>().As<ICacheRepository>(); 
var cacheHelper = new CacheHelper(???); 
builder.RegisterInstance(cacheHelper).As<CacheHelper>(); 

Где CacheHelper класс имеет конструктор зависимость от CacheRepository.

public class CacheHelper 
{ 
    private readonly ICacheRepository _repository; 

    public CacheHelper(ICacheRepository repository) 
    { 
     _repository = repository; 
    } 
} 
+0

Ваша цель сделать 'cacheHelper' синглом? Это может быть достигнуто по-другому. –

ответ

4

Вам не нужно разрешать компонент во время процесса сборки. Autofac способен решать зависимость графа объекта. В вашем случае CacheHelper зависит от ICacheRepository, так что вы просто должны зарегистрировать CacheHelper и ICacheRepository

var builder = new ContainerBuilder(); 
builder.RegisterType<CacheRepository>().As<ICacheRepository>(); 
builder.RegisterType<CacheHelper>().As<CacheHelper>(); 

Когда Autofac рассосется CacheHelper создаст граф зависимостей и создать экземпляр CacheHelper с экземпляром ofsi ICacheRepository. Если вам нужен Singleton, вы можете указать Autofac, чтобы создать только один экземпляр.

var builder = new ContainerBuilder(); 
builder.RegisterType<CacheRepository>().As<ICacheRepository>(); 
builder.RegisterType<CacheHelper>().As<CacheHelper>().SingleInstance(); 

Другим решением было бы зарегистрировать лямбда-выражения, эти регистрации называются, когда вам это нужно, так что вы можете решить вещи в процессе сборки:

var builder = new ContainerBuilder(); 
builder.RegisterType<CacheRepository>().As<ICacheRepository>(); 
builder.Register(c => new CacheHelper(c.Resolve<ICacheRepository>())) 
     .As<CacheHelper>() 
     .SingleInstance(); // It will result of having one CacheHelper whereas 
          // ICacheRepository is declared as .InstancePerDependency 

Будьте осторожны с этим решением, потому что ICacheRepository является объявленный без рамки, по умолчанию будет использоваться область InstancePerDependency. Поскольку CacheHelper - SingleInstance, будет использоваться только один экземпляр ICacheRepository, который может привести к ошибкам. См. Captive Dependency для получения дополнительной информации.

В вашем случае, похоже, вам не нужна такая регистрация.

+0

А, конечно. Имеет смысл. Благодаря! –

+0

Обратите внимание, что в ваших последних двух примерах 'CacheRepository' становится [Captive Dependency] (http://blog.ploeh.dk/2014/06/02/captive-dependency/)' CacheHelper', который часто приводит к в ошибках. – Steven

+0

@Steven: приятно поймать, не видел его при написании моего ответа. Я редактировал свой пост. Благодарю. –

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