C# 在类依赖项上分配属性
假设我有一个类,它接受一个IFileLogger作为构造函数参数C# 在类依赖项上分配属性,c#,.net,unit-testing,design-patterns,tdd,C#,.net,Unit Testing,Design Patterns,Tdd,假设我有一个类,它接受一个IFileLogger作为构造函数参数 public MyClass : IClass { private IFileLogger Logger; public MyClass(IFileLogger Logger) { this.Logger = Logger; } } 在该类的某个地方,它调用Logger.Write(“数据”) IFileLogger具有DirectoryPath属性 这需要设置为IFileLogg
public MyClass : IClass
{
private IFileLogger Logger;
public MyClass(IFileLogger Logger)
{
this.Logger = Logger;
}
}
在该类的某个地方,它调用Logger.Write(“数据”)代码>
IFileLogger具有DirectoryPath属性
这需要设置为IFileLogger知道将文件写入何处
那是怎么设置的
我的想法是在设置的类上有一个属性,然后在构造函数中有类似于IFileLogger.DirectoryPath=this.DirectoryPath的内容
这似乎是错误的,因为IClass需要在其中包含属性,而您最终创建的属性链只在底层需要
你能帮助那些看不见树木的人吗?您是否还会编写测试,以及如何确定IFileLogger的DirectoryPath是否已填充?您如何以及在何处实例化IFileLogger,听起来它是设置其属性的地方
builder.RegisterType<FileLogger>().WithParameter(new NamedParameter("directoryPath", @"c:\temp")).As<IFileLogger>();
builder.RegisterType().WithParameter(新名称Parameter(“directoryPath”,“c:\temp”)).As();
通过这种配置,无论何时使用该生成器解析IFileLogger,它都将使用“c:\Temp”作为directoryPath。通常,我会说,您的对象在构建之后就应该可以使用了,而必须调用其他方法/属性来准备它只是一种混乱。因此,在将其传递到MyClass之前,记录器应该已经设置了DirectoryPath属性。例如:
SomeInitialisationMethod
()
{
// or use IOC "factory" to create necessary concrete version.
IFileLogger logger = new LoggerVariant("path");
// MyClass can now use the ready to use logger. If we need to set the DirectoryPath, we can do it on this calling stack through the logger.
MyClass myClass = new MyClass(logger);
我可以建议您的界面设计是这里的问题,您的问题是气味的指示吗
IFileLogger
表示类所依赖的接口。因此,查看接口,我们看到有一个Write
方法。问题是,MyClass
并不真正关心日志记录是如何发生的,只是它符合接口。话虽如此,MyClass
需要知道目录位置,以便告诉IFileLogger
如何完成它的工作,这种想法告诉您,责任是错误的
代码需要什么IFileLogger
?伐木,对吗?让我们稍微重构一下代码,并根据客户机的需要实现接口,MyClass
。他不在乎日志记录是如何发生的,只在乎它会发生
将接口重命名为ILogger
public MyClass : IClass
{
private ILogger Logger;
public MyClass(ILogger Logger)
{
this.Logger = Logger;
}
}
现在,在这个类的任何地方都没有对“文件”的引用,这使得目录设置显然不属于这里。它属于哪里?可能在文件记录器
本身中
使用依赖项注入会给您带来如下结果:
main() {
// Poor man's DI, no frameworks here
var logger = new FileLogger("some/directory");
var instance = new MyClass(logger);
return instance.DoSomethingUsefulThatEventuallyGetsLogged();
}
希望有帮助
Brandon在这种情况下,FileLogger构造函数应该在参数中采用RepositoryPath(当然,应该将其设置为RepositoryPath属性),并且在解析IFileLogger时应该插入该参数。是否尝试使用类似container.resolve(新名称参数(“dirPath”)的内容解析DirectoryoPath参数,@“c:\temp”);不,我想这可能行得通,但我需要一个包含容器的静态类,这是否意味着当IOC创建IFileLogger实例时,它将始终使用该参数?如果MyClass ie IClass是具有InitlisationMethod的类上的构造函数参数呢?这就是我的代码的样子