2013-02-21 4 views
0

У меня есть проект ASP.NET MVC с 2 экземплярами интерфейса репозитория базы данных (IDBSessionFactory): один для базы данных данных и один для базы данных config. В моем загрузчике, это как я разводка на DI:Autofac - Инъекция конкретного экземпляра интерфейса

// using ... 

builder.Register(c => new DbSessionFactory("dataDB", Assembly.GetExecutingAssembly())) 
    .Named<IDbSessionFactory>("datadb") 
    .InstancePerHttpRequest() 
    .InstancePerApiRequest(); 

builder.Register(c => new DbSessionFactory("configDB", Assembly.GetExecutingAssembly())) 
    .Named<IDbSessionFactory>("configdb") 
    .InstancePerHttpRequest() 
    .InstancePerApiRequest(); 

builder.RegisterControllers(Assembly.GetExecutingAssembly()); 

У меня есть некоторые классы контроллеров, которые нуждаются в "configDB" экземпляре IDBSessionFactory в качестве входного параметра. Как мне добиться этого?

Любая помощь приветствуется.

ответ

2

я понял это. Вы должны использовать с параметрами при регистрации контроллеров. Моя стратегия - зарегистрировать ВСЕ контроллеры в отношении параметра datadb, а затем зарегистрировать определенные контроллеры в отношении параметра configdb. Единственное, что нужно посмотреть, это сохранить имена параметров во всех классах контроллеров.

builder.RegisterControllers(Assembly.GetExecutingAssembly()).WithParameters(new[] { 
         new ResolvedParameter((p, c) => p.Name == "dbSessionFactory", (p, c) => c.ResolveNamed<IDbSessionFactory>("datadb")) 
        }); 

// Register controllers which need a specific named type    
builder.RegisterType<Web.Controllers.AdminController>().WithParameters(new[] { new ResolvedParameter((p, c) => p.Name == "sessionFactory", (p, c) => c.ResolveNamed<IDbSessionFactory>("configdb")) }); 
// Wire up the account controller with the config database instance, since all the user tables are there 
builder.RegisterType<Web.Controllers.AccountController>().WithParameters(new[] { 
         new ResolvedParameter((p, c) => p.Name == "dbSessionFactory", (p, c) => c.ResolveNamed<IDbSessionFactory>("configdb")) 
         , new ResolvedParameter((p,c) => p.Name == "logger",(p,c) => c.Resolve<ILogger>()) 
         , new ResolvedParameter((p,c) => p.Name == "formsAuth",(p,c) => c.Resolve<IFormsAuthentication>()) 
        }); 
0

В Autofac регистрации являются последними в истории. Это означает, что после того, как вы вызовете RegisterControllers, вы можете просто сделать одноразовые регистрации для контроллеров, которые вы хотите переопределить, и они вступят в силу.

Пример:

builder.RegisterControllers(Assembly.GetExecutingAssembly()); 

builder.Register(c => 
    new FooController(c.ResolveNamed<IDbSessionFactory>("configDB"))); 

// ... 

container.Resolve<FooController>() // Resolves FooController with configDB 
+0

Уверены ли вы? Когда я делаю то, что вы предлагали, Autofac выдает исключение, потому что он не знает, какой экземпляр для инъекции, так как я зарегистрировал 2 именованных экземпляра в моем примере выше. –

+0

@Shailen Sukul: Предположим, у вас есть контроллер с именем 'FooController', который регистрирует регистрацию регистраторов. Затем вы можете зарегистрировать 'FooController' вручную и ссылаться на компоненты« configDB »или« dataDB »через' ResolveNamed'. При разрешении 'FooController', Autofac предоставит вашу регистрационную информацию * вместо автоматической. Имеет ли это смысл? –

+0

Я использовал ResolveNamed вместе с ResolvedParameter, чтобы заставить его работать .. комбинация сделала трюк для меня .. Моя точка была последней в выигрыше, часть не работала должным образом. Мне пришлось явно привязывать каждого контроллера к определенному экземпляру класса IDBSessionFactory .. благодарит за вашу помощь –