Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在类依赖项上分配属性_C#_.net_Unit Testing_Design Patterns_Tdd - Fatal编程技术网

C# 在类依赖项上分配属性

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

假设我有一个类,它接受一个IFileLogger作为构造函数参数

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的类上的构造函数参数呢?这就是我的代码的样子