加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如何使用Simple Injector注册命名实例

发布时间:2020-12-15 17:59:49 所属栏目:百科 来源:网络整理
导读:我正在开发一个WinForm应用程序,我正在使用Repository Pattern,我使用Servicestack OrmLite进行数据访问,使用Simple Injector进行IoC. 在我的program.cs中我有2个注册2个不同的OrmLiteConnectionFactory但是目前我无法因为我无法注册命名…用FunQ我可以用 co
我正在开发一个WinForm应用程序,我正在使用Repository Pattern,我使用Servicestack OrmLite进行数据访问,使用Simple Injector进行IoC.

在我的program.cs中我有2个注册2个不同的OrmLiteConnectionFactory但是目前我无法因为我无法注册命名…用FunQ我可以用

container.Register<IDbConnectionFactory>("db1",_ => new OrmLiteConnectionFactory(
    ConfigurationManager.ConnectionStrings["db1"].ConnectionString,SqlServerDialect.Provider));
container.Register<IDbConnectionFactory>("db2",_ => new OrmLiteConnectionFactory(
    ConfigurationManager.ConnectionStrings["db2"].ConnectionString,SqlServerDialect.Provider));

这是我的program.cs Bootstrap方法

private static void Bootstrap()
{
    // Create the container as usual.
    Container = new Container();

    string conn1 = ConfigurationManager.ConnectionStrings["dbconn1"].ConnectionString;
    string conn2 = ConfigurationManager.ConnectionStrings["dbconn2"].ConnectionString;

    OrmLiteConnectionFactory connectionFactory = new OrmLiteConnectionFactory(conn1,ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance); 
    Container.RegisterSingle<OrmLiteConnectionFactory>(connectionFactory1);

    OrmLiteConnectionFactory connectionFactory2 = new OrmLiteConnectionFactory(conn2,ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance); 

    // how do I register this one without a name?
    Container.RegisterSingle<OrmLiteConnectionFactory>(connectionFactory2);

    Container.Register<MainForm>();
}

提前致谢

解决方法

由于您有两个不同的数据库,每个数据库都有不同的模式,因此不同的OrmLiteConnectionFactory不可互换.这意味着如果你交换它们,你的系统将停止工作.这表明你打破了 Liskov Substitution Principle.因此,在这种情况下的一般解决方案是为每个工厂提供自己的接口,并让每个存储库依赖于该特定接口.这允许您唯一地注册它们,让容器毫无疑问地解析对象图.

如果给每个工厂自己的抽象不是一种选择,或者方便,另一种选择是注册你的存储库而不需要自动连接.通过向委托人注册您的存储库,您可以完全控制注入存储库的内容.例如:

container.Register<IOrderRepository>(() => new SqlOrderRepo(connectionFactory1));

container.Register<IUserRepository>(() => new SqlUserRepo(
    connectionFactory2,container.GetInstance<ILogger>()));

第三种选择是使用context based injection,如果您执行以下操作:

var f1 = Lifestyle.Singleton.CreateRegistration<IDbConnectionFactory>(
    () => new OrmLiteConnectionFactory(
            conn1,ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance),container);

var f2 = Lifestyle.Singleton.CreateRegistration<IDbConnectionFactory>(
    () => new OrmLiteConnectionFactory(
            conn2,container);

container.RegisterConditional(typeof(IDbConnectionFactory),f1,InjectedInto<SqlOrderRepo>);
container.RegisterConditional(typeof(IDbConnectionFactory),f2,InjectedInto<SqlUserRepo>);

// Helper method.
static bool InjectedInto<T>(PredicateContext c) =>
    c.Consumer.ImplementationType == typeof(T);

开箱即用Simple Injector不支持注册键控注册,但有几种方法可以执行此操作,如page所述.该页面还解释了为什么没有内置支持.这是一个深思熟虑的设计决定.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读