我试图让Unity管理我的对象的创建,我希望有一些在运行时才知道的初始化参数:
目前,我能想到的方法是在接口上使用Init方法.
interface IMyIntf {
void Initialize(string runTimeParam);
string RunTimeParam { get; }
}
Run Code Online (Sandbox Code Playgroud)
然后使用它(在Unity中)我会这样做:
var IMyIntf = unityContainer.Resolve<IMyIntf>();
IMyIntf.Initialize("somevalue");
Run Code Online (Sandbox Code Playgroud)
在这种情况下,runTimeParamparam是在运行时根据用户输入确定的.这里的简单案例只返回值,runTimeParam但实际上参数将类似于文件名,初始化方法将对文件执行某些操作.
这会产生许多问题,即该Initialize方法在界面上可用并且可以多次调用.在实现中设置一个标志并在重复调用时抛出异常Initialize似乎很笨重.
在解析我的界面时,我不想知道有关实现的任何信息IMyIntf.但是,我想要的是知道这个接口需要一定的一次初始化参数.有没有办法以某种方式注释(属性?)具有此信息的接口,并在创建对象时将它们传递给框架?
编辑:更多地描述了界面.
interface-design dependency-injection ioc-container inversion-of-control unity-container
我熟悉这些模式,但仍然不知道如何处理以下情况:
public class CarFactory
{
public CarFactory(Dep1,Dep2,Dep3,Dep4,Dep5,Dep6)
{
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return new Car1(Dep1,Dep2,Dep3);
break;
case B:
return new Car2(Dep4,Dep5,Dep6);
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
通常,问题在于需要注入的引用量.当有更多的汽车时会更糟.
我想到的第一种方法是在工厂构造函数中注入Car1和Car2,但它违反工厂方法,因为工厂将始终返回相同的对象.第二种方法是注入servicelocator,但它的反模式到处都是.怎么解决?
替代方式1:
public class CarFactory
{
public CarFactory(IContainer container)
{
_container = container;
}
public ICar CreateCar(type)
{
switch(type)
{
case A:
return _container.Resolve<ICar1>();
break;
case B:
return _container.Resolve<ICar2>();
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
替代方式2(由于树中的依赖性过多而难以使用):
public class CarFactory
{
public CarFactory()
{
}
public ICar CreateCar(type)
{
switch(type)
{ …Run Code Online (Sandbox Code Playgroud) c# dependency-injection inversion-of-control factory-pattern
关于这个话题的讨论很多,但每个人似乎都错过了一个明显的答案.我想帮助审查这个"明显的"IOC容器解决方案.各种对话假设运行时选择策略和使用IOC容器.我将继续这些假设.
我还想补充一个假设,即它不是必须选择的单一策略.相反,我可能需要检索一个对象图,该对象图在整个图的节点中找到了几个策略.
我将首先快速概述两个常用的解决方案,然后我将展示我希望看到IOC容器支持的"明显"替代方案.我将使用Unity作为示例语法,但我的问题不是Unity特有的.
这种方法要求每个新策略都手动添加绑定:
Container.RegisterType<IDataAccess, DefaultAccessor>();
Container.RegisterType<IDataAccess, AlphaAccessor>("Alpha");
Container.RegisterType<IDataAccess, BetaAccessor>("Beta");
Run Code Online (Sandbox Code Playgroud)
......然后明确要求正确的策略:
var strategy = Container.Resolve<IDataAccess>("Alpha");
Run Code Online (Sandbox Code Playgroud)
为了说明这种方法,假设以下类:
public class DataAccessFactory{
public IDataAccess Create(string strategy){
return //insert appropriate creation logic here.
}
public IDataAccess Create(){
return //Choose strategy through ambient context, such as thread-local-storage.
}
}
public class Consumer
{
public Consumer(DataAccessFactory datafactory)
{
//variation #1. Not sufficient to meet requirements.
var myDataStrategy = datafactory.Create("Alpha");
//variation #2. This is sufficient for requirements.
var myDataStrategy = …Run Code Online (Sandbox Code Playgroud) 我的Web应用程序在业务逻辑和表示逻辑上有一些细微的变化,具体取决于登录用户的类型.看起来通过根据用户类型注入不同的具体类来获得变化非常适合DI.所以我想知道我应该使用StructureMap的哪些功能来实现这一目标(或者如果我基于DI的目的而离开).
(我刚刚了解到配置文件不是实现此目的的方法,因为设置配置文件不是每线程操作:StructureMap配置文件线程安全吗?)
这是怎么回事?
public class HomeController
{
private ISomeDependancy _someDependancy;
public HomeController(ISomeDependancy someDependancy)
{
_someDependancy = someDependancy;
}
public string GetNameFromDependancy()
{
return _someDependancy.GetName();
}
}
public interface ISomeDependancy
{
string GetName();
}
public class VersionASomeDependancy : ISomeDependancy
{
public string GetName()
{
return "My Name is Version A";
}
}
public class VersionBSomeDependancy : ISomeDependancy
{
public string GetName()
{
return "My Name is Version B";
}
}
public class VersionARegistry : Registry
{
public VersionARegistry() …Run Code Online (Sandbox Code Playgroud)