首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在ServiceStack.net中使用Funq注册多个IDbConnectionFactory实例

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

Stack Overflow用户
提问于 2012-01-07 04:35:01
回答 5查看 8.4K关注 0票数 19

如何在Funq中注册不同的IDbConnectionFactory实例,然后在您的服务中直接访问它们?命名实例在这里起作用了吗?

当跨服务使用不同的数据库时,这是最好的方法吗?

谢谢!

编辑:

一个例子;)。我可能说错了,因为我是IoC的新手,但是比方说,我有两个单独的数据库连接,我想注入它们。在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));                

这两个似乎都注入了白兰地多利。

然后在服务端通过如下方式自动访问这些内容:

public IDbConnectionFactory DbFactory { get; set; }

在这种情况下,它似乎给了我第一个注册的。如何在服务端访问特定的服务?希望这能让事情变得更清楚一些。

下面是一个来自ServiceStack.Examples的完整示例,它只使用一个IDbConnectionFactory:Movies Rest

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-01-07 08:49:29

我上面的问题仍然有效,但下面的问题可能会对你有所帮助。

Funq不支持自动构造函数注入(也称为自动连接),您必须通过构造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不支持自动连接。你将是那个手动将所有东西连接在一起的人。但是,当您切换到支持自动连接的框架时,这种设计允许容器注入正确的依赖项而不会出现问题,因为没有讨论要注入什么。

票数 15
EN

Stack Overflow用户

发布于 2012-01-08 21:34:52

尽管Funq不支持自动布线,但它的ServiceStack实现支持。最新版本的ServiceStack包含Funq.Container重载:

container.RegisterAutoWired<T>();
container.RegisterAutoWiredAs<T,TAs>();
container.RegisterAs<T,TAs>();

因此,在Steven的示例中,您还可以这样做:

container.RegisterAs<YellowDbConnectionFactory,IYellowDbConnectionFactory>();

它会自动为你注册依赖项。

票数 11
EN

Stack Overflow用户

发布于 2015-10-25 19:29:41

我想我应该在这里加入我的2分钱,尽管我意识到这个问题已经很老了。我想从ServiceStack访问事务数据库和日志数据库,这就是我最终从AppHostBase Configure()方法访问事务数据库和日志数据库的方式:

            container.Register<IDbConnectionFactory>(
                c => {
                    OrmLiteConnectionFactory dbFactory = new OrmLiteConnectionFactory(ConfigurationManager.ConnectionStrings["MyTransactionalDB"].ConnectionString, MySqlDialect.Provider);
                    dbFactory.ConnectionFilter = x => new ProfiledDbConnection(x, Profiler.Current);
                    dbFactory.RegisterConnection("LoggingDB", ConfigurationManager.ConnectionStrings["MyLoggingDB"].ConnectionString, MySqlDialect.Provider);

                    return dbFactory;
                });

默认情况下,从工厂打开连接时使用"MyTransactionalDB“,但我可以通过以下方式从服务显式访问日志数据库:

        using (var db = DbFactory.Open("LoggingDB"))
        {
            db.Save(...);
        }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8764125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档