我试图让Unity来管理我的对象的创建,我想有一些初始化参数,直到运行时才知道:
interface IMyIntf { void Initialize(string runTimeParam); string RunTimeParam { get; } }
然后使用它(在Unity中)我会这样做:
var IMyIntf = unityContainer.Resolve<IMyIntf>(); IMyIntf.Initialize("somevalue");
在这种情况下,runTimeParam参数在运行时基于用户输入确定。这里的简单例子只返回runTimeParam的值,但实际上参数将像文件名和initialize方法将做一些与文件。
这会产生一些问题,即初始化方法在接口上可用,可以多次调用。在实现中设置一个标志,并在重复调用Initialize时抛出异常似乎很笨重。
在我解决我的界面,我不想知道任何关于IMyIntf的实现。但我想要的是知道这个接口需要一定的一次性初始化参数。有没有办法以某种方式用这个信息注释(属性?)接口,并将这些传递到框架当对象被创建?
编辑:描述接口多一点。
任何需要运行时值来构造特定依赖关系的地方,Abstract Factory是解决方案。
对接口的初始化方法漏洞抽象的气味。
在你的情况下,我会说,你应该建模IMyIntf接口,如何你需要使用它 – 不是你打算如何创建它的实现。这是一个实现细节。
因此,接口应该简单地是:
public interface IMyIntf { string RunTimeParam { get; } }
现在定义抽象工厂:
public interface IMyIntfFactory { IMyIntf Create(string runTimeParam); }
现在可以创建一个具体的IMyIntfFactory实现,创建IMyIntf的具体实例,如下所示:
public class MyIntf : IMyIntf { private readonly string runTimeParam; public MyIntf(string runTimeParam) { if(runTimeParam == null) { throw new ArgumentNullException("runTimeParam"); } this.runTimeParam = runTimeParam; } public string RunTimeParam { get { return this.runTimeParam; } } }
注意这是如何允许我们通过使用readonly关键字来保护类的不变量。无臭有必要初始化方法。
一个IMyIntfFactory实现可能是这样简单:
public class MyIntfFactory : IMyIntfFactory { public IMyIntf Create(string runTimeParam) { return new MyIntf(runTimeParam); } }
在所有的消费者,你需要一个IMyIntf实例,你只需要依赖于IMyIntfFactory通过请求它通过构造函数注入。