c# – 使用primitive-arguments构造函数注册一个类型?

前端之家收集整理的这篇文章主要介绍了c# – 使用primitive-arguments构造函数注册一个类型?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个类在其构造函数中有一些原始类型参数,如字符串等.

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

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;
  }
}

更新:
请记住,IRegionManager和IEventAggregator是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,LoginManagerConfiguration configuration)
{
    ...
}

LoginManagerConfiguration可以像这样注册

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

指定应用程序范围的配置对象而不是此类型特定的DTO可能很诱人,但这是一个陷阱.这种应用程序范围的配置对象是Service Locator反模式的配置等价物.不清楚类型需要什么配置值,并使类更难测试.

选项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:使用工厂代表

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

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

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

猜你在找的C#相关文章