上面我的问题仍然有效,但以下可能会帮助你的好意。
Funq不支持自动构造函数注入(a.k.a.自动布线),您将不得不通过构造Func<T>
lambda表达式来手动执行此操作。因为您已经手动进行构造函数注入,所以很容易选择您希望注入到服务中的什么IDbConnectionFactory
。例如:
IDbConnectionFactory yellowDbConFactory =
new YellowDbConnectionFactory();
IDbConnectionFactory blueDbConFactory =
new BlueDbConnectionFactory();
IDbConnectionFactory purpleDbConFactory =
new PurpleDbConnectionFactory();
container.Register<IService1>(c =>
new Service1Impl(yellowDbConFactory,
c.Resolve<IDep1>());
container.Register<IService2>(c =>
new Service2Impl(blueDbConFactory);
container.Register<IService3>(c =>
new Service3Impl(purpleDbConFactory,
c.Resolve<IDep2>());
当然,你也可以将旧命名注册,就像这样:
container.Register<IDbConnectionFactory>("yellow",
new YellowDbConnectionFactory());
container.Register<IDbConnectionFactory>("blue",
new BlueDbConnectionFactory());
container.Register<IDbConnectionFactory>("purple",
new PurpleDbConnectionFactory());
container.Register<IService1>(c =>
new Service1Impl(
c.Resolve<IDbConnectionFactory>("yellow"),
c.Resolve<IDep1>());
container.Register<IService2>(c =>
new Service2Impl(
c.Resolve<IDbConnectionFactory>("blue"));
container.Register<IService3>(c =>
new Service3Impl(
c.Resolve<IDbConnectionFactory>("purple"),
c.Resolve<IDep2>());
由于缺乏对自动装配支持的,你最终会与这些比较尴尬注册,这很快就会导致构建根目录的维护噩梦,但这与您的问题无关;-)
您通常应该尽量避免注册时出现歧义。在你的情况下,你有一个单一的接口,它做两件事(连接到两个数据库)。除非这两个数据库共享完全相同的模型中,每个数据库应该得到自己的接口(如果这两个实现并不互换,你会违反Liskov substitution principle):
interface IYellowDbConnectionFactory : IDbConnectionFactory
{
}
interface IPurpleDbConnectionFactory : IDbConnectionFactory
{
}
因为这样ServiceStack作品,你可能需要实现每个实现:
class YellowDbConnectionFactory : OrmLiteConnectionFactory,
IYellowDbConnectionFactory
{
public YellowDbConnectionFactory(string s) : base(s){}
}
class PurpleDbConnectionFactory : OrmLiteConnectionFactory,
IPurpleDbConnectionFactory
{
public YellowDbConnectionFactory(string s) : base(s){}
}
现在,你应该改变你的服务的定义中使用的,而不是使用IDbConnectionFactory
具体接口:
public class MovieService : RestServiceBase<Movie>
{
private readonly IYellowDbConnectionFactory dbFactory;
public MovieService(IYellowDbConnectionFactory factory)
{
this.dbFactory = factory;
}
}
请注意,此类现在使用构造函数注入而不是属性注入。你可以使用这个来处理属性注入,但通常使用构造函数注入更好。这是关于它的SO question。
随着Funq,你的配置然后将这个样子:
container.Register<MovieService>(c =>
new MovieService(
c.Resolve<IYellowDbConnectionFactory>());
这两个新的接口和两个类并切换到MovieService
没赢你很多,因为Funq不支持自动接线。你将是一个手动将所有东西连接在一起的人。但是,当您切换到确实支持自动布线的框架时,此设计允许容器注入正确的依赖关系而没有问题,因为没有关于要注入什么的讨论。
你能显示一些代码吗?我想我们可以给你一些关于你的应用程序设计的提示,但为此,我们需要更多的实际设计见解。看看在哪些服务中注入了这些IDbConnectionFactory实例,以及这些服务如何处理这些IDbConnectionFactory依赖关系会很有趣。 – Steven 2012-01-07 00:23:25
但请注意,Funq是一个非常简单的IoC容器(有些甚至可能认为它不是IoC容器),而且所有东西都必须通过手工连接。但是,您可以在创建的每项服务中注入所需的一切。 – Steven 2012-01-07 00:25:55
我更新了这个问题,使其更加清晰,并在Simple Injector上找到了您的文章。我希望通过现在的阅读来加深对IoC的理解。 – 2012-01-07 03:24:33