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; } } 更新: 这会被视为坏习惯吗?有更好的选择吗? 解决方法
尝试防止在构造函数中具有原始或难以解析类型的类设计.正如你已经从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")); })); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |