gpt4 book ai didi

c# - 如何在 ServiceStack.net 中使用 Funq 注册多个 IDbConnectionFactory 实例

转载 作者:IT王子 更新时间:2023-10-29 04:48:26 27 4
gpt4 key购买 nike

您将如何在 Funq 中注册不同的 IDbConnectionFactory 实例,然后直接在您的服务中访问它们?命名实例是否以某种方式在这里发挥作用?

这是跨服务使用不同数据库时采用的最佳方法吗?

谢谢!

编辑:

一个例子 ;)。我可能离这里很远,因为我对 IoC 还很陌生,但是举例来说,我有 2 个独立的数据库连接要注入(inject)。在 ServiceStack 中,这是在 Global.asax 中完成的。

container.Register<IDbConnectionFactory>(c =>
new OrmLiteConnectionFactory(@"Connection String 1", SqlServerOrmLiteDialectProvider.Instance));

container.Register<IDbConnectionFactory>(c =>
new OrmLiteConnectionFactory(@"Connection String 2", SqlServerOrmLiteDialectProvider.Instance));

这两个似乎都注入(inject)了 honky dory。

然后通过类似这样的方式在服务端自动访问这些:

public IDbConnectionFactory DbFactory { get; set; }

在这种情况下,它似乎是给我第一个注册的。我怎样才能访问服务端的特定一个?希望这能让它更清楚一点。

这是来自 ServiceStack.Examples 的完整示例,它仅使用 1 个 IDbConnectionFactory: Movies Rest

最佳答案

我上面的问题仍然有效,但以下内容可能对您有所帮助。

Funq 不支持自动构造函数注入(inject)(又名 Autowiring ),您必须通过构造 Func<T> 来手动执行此操作 lambda 表达式。因为你已经在手动进行构造函数注入(inject),所以很容易选择什么 IDbConnectionFactory您希望注入(inject)您的服务。示例:

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>());

由于缺乏对 Autowiring 的支持,你最终会遇到这些相当尴尬的注册,这很快就会导致你的组合根的维护噩梦,但这与你的问题无关;-)

您通常应该尽量避免在注册时出现歧义。在您的情况下,您只有一个界面,它可以做两件事(连接到两个数据库)。除非两个数据库共享完全相同的模型,否则每个数据库都应该有自己的接口(interface)(如果两个实现不可互换,您将违反 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){}
}

现在您应该更改服务的定义以使用特定接口(interface)而不是使用 IDbConnectionFactory :

public class MovieService : RestServiceBase<Movie>
{
private readonly IYellowDbConnectionFactory dbFactory;

public MovieService(IYellowDbConnectionFactory factory)
{
this.dbFactory = factory;
}
}

请注意,此类现在使用构造函数注入(inject)而不是属性注入(inject)。你可以让它与属性注入(inject)一起工作,但通常最好使用构造函数注入(inject)。这是一个 SO question关于它。

使用 Funq,您的配置将如下所示:

container.Register<MovieService>(c =>
new MovieService(
c.Resolve<IYellowDbConnectionFactory>());

这两个新接口(interface)和两个类并更改为 MovieService没有赢得你很多,因为 Funq 不支持自动布线。您将是手动将所有内容连接在一起的人。然而,当您切换到一个确实支持 Autowiring 的框架时,这种设计允许容器毫无问题地注入(inject)正确的依赖项,因为没有讨论注入(inject)什么。

关于c# - 如何在 ServiceStack.net 中使用 Funq 注册多个 IDbConnectionFactory 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8764125/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com