如何使用简单注入器注册命名实例

本文关键字:实例 注册 注入器 何使用 简单 | 更新日期: 2023-09-27 18:34:44

我正在开发一个WinForm应用程序,我正在使用Repository Pattern,我正在使用Servicestack OrmLite进行数据访问,并使用Simple Injectator进行IoC。

在我的程序中.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));

这是我的程序.cs 引导方法

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不可互换。这意味着如果您交换它们,您的系统将停止工作。这表明你正在打破利斯科夫替代原则。因此,在这种情况下,一般解决方案是为每个工厂提供自己的接口,并让每个存储库依赖于该特定接口。这允许您唯一地注册它们,并让容器毫无疑问地解析对象图。

如果为每个工厂提供自己的抽象不是一种选择或方便,另一种选择是在不自动连线的情况下注册存储库。通过向委托注册存储库,您可以完全控制要注入存储库的内容。例如:

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

第三个选项是使用基于上下文的注入,如果您执行以下操作:

var f1 = Lifestyle.Singleton.CreateRegistration<IDbConnectionFactory>(
    () => new OrmLiteConnectionFactory(
            conn1,
            ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance), 
        container);
var f2 = Lifestyle.Singleton.CreateRegistration<IDbConnectionFactory>(
    () => new OrmLiteConnectionFactory(
            conn2,
            ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.Instance), 
        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);

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