gpt4 book ai didi

c# - 在容器中注册 bool 值

转载 作者:行者123 更新时间:2023-11-30 14:29:10 25 4
gpt4 key购买 nike

我正在重写我公司的 DAO 库。由于我们解决方案的特点,我们需要根据客户切换ADO库(Oracle/SQL Server)。由于静态引用是我们问题的主要来源(f.e.Oracle 包取自 CI 而不是 SQL Server),我决定采用插件架构,并尝试动态加载所需的 dll。

我是 Simple Injector 的新手(我使用的是 Ninject,但在这种情况下,我们需要一些非常快的东西)。我用了https://simpleinjector.readthedocs.org/en/latest/advanced.html#registering-plugins-dynamically文章并设法将正确的 dll 加载到域中。

我目前在容器验证 (container.Verify()) 期间遇到一个奇怪的(在我看来)错误:

The constructor of type GenericDAO contains the parameter of type Boolean with name 'isInUserContext' that is not registered. Please ensure Boolean is registered in the container, or change the constructor of GenericDAO.

我的构造函数看起来像这样:

public class GenericDAO : DBHelper
{

public GenericDAO(Boolean isInUserContext, string connectionString, string providerName, UniversalDataAccess universalDataAccess)
: base(isInUserContext, connectionString, providerName, universalDataAccess)
{
}

我的注册:

var pluginDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");

var pluginAssemblies =
from file in new DirectoryInfo(pluginDirectory).GetFiles()
where file.Extension.ToLower() == ".dll"
select Assembly.LoadFile(file.FullName);

var pluginTypes =
from assembly in pluginAssemblies
from type in assembly.GetExportedTypes()
where typeof (IDBHelper).IsAssignableFrom(type)
where !type.IsAbstract
where !type.IsGenericTypeDefinition
select type;

_kernel.RegisterAll<IDBHelper>(pluginTypes);

你知道如何成功初始化所有需要的类型吗?我想公开 GenericDAO 类型的公共(public)属性。

最佳答案

异常消息有点误导,因为 Simple Injector 不允许您在容器中注册原始类型(例如 Boolean ),所以实际上容器会建议您做一些不可能做的事情。

Simple Injector 不允许您注册诸如 int、bool、string 等原语的原因是这些类型是不明确的。 .NET 中的 DI 容器根据类型信息注入(inject)服务,但您的代码库中的所有组件都不太可能需要 string在他们的构造函数中,实际上需要完全相同的值。有些人期望连接字符串,其他人期望一些文件路径。但是如果你能注册 string在容器中,您只能指定一个值(例如连接字符串),从而无法注入(inject)另一个值(例如文件路径)。

然而,这个问题并不是 Simple Injector 特有的,这是一个普遍的问题。然而,其他 DI 容器可能允许您解析在构造函数中采用原始值的组件,并可能用一些默认值填充此值。这几乎没有用,因为如果您只需要该原始类型的默认值,为什么还要通过构造函数公开此类型?

很难说您应该如何解决这个问题。一般来说,如果一个类型需要一些配置值,你需要明确地告诉你的容器应该如何解析这个类型。使用 Simple Injector,这将如下所示:

container.Register<GenericDAO>(() => new GenericDAO(
isInUserContext: true,
connectionString: "con str",
providerName: "System.Sql.Client",
universalDataAccess: container.GetInstance<UniversalDataAccess>()));

但是,如果您有多个(或许多)组件需要相同的配置值,这通常意味着您缺少抽象。例如,isInUserContext , 可能是一个应该隐藏在 IUserContext 后面的值抽象和 connectionStringproviderName闻起来像 IDbConnectionFactory抽象或类似的东西。在后一种情况下 GenericDAO类会将创建连接的责任转移到不同的类中,使其能够专注于它所承担的责任。

在这种情况下 GenericDAO的构造函数如下所示:

public GenericDAO(IUserContext userContext, IDbConnectionFactory connectionFactory,
UniversalDataAccess universalDataAccess)

现在因为构造函数不再有原始参数,类现在可以由容器 Autowiring 。在 Simple Injector 中,您现在可以按如下方式注册它:

container.Register<GenericDAO>();

在您的案例中优势变得尤为明显,因为您正在批量注册 GenericDAO作为插件。所有批量注册的类型都必须是可 Autowiring 的才能成功。

当然你必须注册 IUserContextIDbConnectionFactory同样,它们可能仍然依赖于一些原始值:

container.RegisterSingle<IUserContext>(new AspNetUserContext());
container.RegisterSingle<IDbConnectionFactory>(
new SqlServerDbConnectionFactory("con str"));

IUserContextIDbConnectionFactory需要在 Bootstrap 和插件程序集都引用的某些中央程序集中定义抽象。

另一种选择是让插件程序集自己注册插件。缺点是那些插件程序集需要依赖于您的 DI 容器。简单注入(inject)器包含一个 SimpleInjector.Packaging允许您在插件程序集中创建“包”的 NuGet 项目。例如:

public class Plugin1Bootstrapper : IPackage
{
public void RegisterServices(Container container) {
container.Register<GenericDAO>(() => new GenericDAO(
isInUserContext: true,
connectionString: "con str",
providerName: "System.Sql.Client",
universalDataAccess: container.GetInstance<UniversalDataAccess>()));

// other registrations here.
}
}

在你的应用程序的启动路径中,你可以调用:

container.RegisterPackages(pluginAssemblies);

这将加载所有 IPackage提供的程序集的实现,并将调用 RegisterServices在他们每个人身上。

请注意,我们注册了 GenericDAO这里又是通过它的具体类型。您可以将其与 RegisterAll<IDBHelper>(...) 混合使用你已经在使用了。 RegisterAll注册将为集合中的每个元素回调到容器中,因此通过使用 Register<GenericDAO> 注册具体类型允许明确指定简单注入(inject)器必须如何解析该具体类型。否则,Simple Injector 将尝试自动连接该具体类型并将其解析为 transient 。

关于c# - 在容器中注册 bool 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27107450/

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