gpt4 book ai didi

c# - 使用原始参数构造函数注册类型?

转载 作者:太空狗 更新时间:2023-10-29 20:57:22 24 4
gpt4 key购买 nike

我有一个类,它的构造函数中有一些原始类型参数,例如字符串等。

我应该如何向统一容器注册类型?

public LoginManager(
IRegionManager regionManager,
IEventAggregator eventAggregator,
string mainRegionName,
Uri login,
Uri target)
{
this.regionManager = regionManager;
this.eventAggregator = eventAggregator;
this.mainRegionName = mainRegionName;
this.login = login;
this.target = target;
}
}

更新:
请记住,IRegionManagerIEventAggregator 是 Prism UnityBootstrapper 的已知类型,在我的例子中它是容器包装器。我必须重新注册他们吗?我希望类型注册尽可能简单。

这会被视为坏习惯吗?还有更好的选择吗?

最佳答案

尽量避免类设计在构造函数中包含原始类型或难以解析的类型。正如您已经从 Tavares 的回答中看到的那样,您的配置变得非常脆弱(更新:Tavares 似乎出于我不清楚的原因删除了他的回答)。您失去了编译时支持,对该构造函数的每次更改都会使您更改 DI 配置。

有多种方法可以更改您的设计以防止出现这种情况。哪一个适用于您取决于您​​,但这里有一些想法:

选项 1:使用不可变配置 DTO:

private sealed class LoginManagerConfiguration
{
public Uri Login { get; private set; }
public Uri Target { get; private set; }
public string MainRegionName { get; private set; }

public LoginManagerConfiguration(Uri login, Uri target, string mainRegionName)
{
this.Login = login;
this.Target = target;
this.MainRegionName = mainRegionName;
}
}

现在您可以让您的 LoginManager 依赖于 LoginManagerConfiguration:

public LoginManager(IRegionManager regionManager,
IEventAggregator eventAggregator,
LoginManagerConfiguration configuration)
{
...
}

LoginManagerConfiguration 可以像这样简单地注册:

container.RegisterInstance<LoginManagerConfiguration>(
new LoginManagerConfiguration(
login: new Uri("Login"),
target: new Uri("Target"),
mainRegionName: ConfigurationManager.AppSettings["MainRegion"]));

指定一个应用程序范围的配置对象而不是这个特定于类型的 DTO 可能很诱人,但这是一个陷阱。这种应用程序范围的配置对象相当于服务定位器反模式的配置。类型需要什么配置值变得不清楚,并且使类更难测试。

选项 2:从该类派生

另一种选择是从该类派生,仅用于 DI 配置。当您无法更改类签名时(即当它是第三方组件时),这尤其有用:

private sealed class DILoginManager : LoginManager
{
DILoginManager(IRegionManager regionManager,
IEventAggregator eventAggregator)
: base(regionManager, eventAggregator,
ConfigurationManager.AppSettings["MainRegion"],
new Uri("Login"),
new Uri("Target"))
{
...
}
}

在您的应用程序的组合根附近定义此类。此类成为您的 DI 配置的实现细节。您的类型的注册现在将非常简单:

container.RegisterType<ILoginManager, DILoginManager>();

尽管调用延迟加载配置值时要非常小心,例如 ConfigurationManager.AppSettings["MainRegion"]。这很容易导致在应用程序启动期间未捕获配置错误的情况,这确实是可取的。

选项 3:使用工厂委托(delegate)

我想提出的最后一个选项是工厂。这看起来很像 Traveses 的回答,但类型安全性更高:

var mainRegion = ConfigurationManager.AppSettings["MainRegion"];

container.Register<ILoginManager>(new InjectionFactory(c =>
{
return new LoginManager(
c.Resolve<IRegionManager>(),
c.Resolve<IEventAggregator>(),
ConfigurationManager.AppSettings["MainRegion"],
new Uri("Login"),
new Uri("Target"));
}));

关于c# - 使用原始参数构造函数注册类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6010088/

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