如何在C#中调用通过Structure Map实例化的类的构造函数

戈帕尔·钱达克

我有一个名为 ILogger 的接口,它基本上包含一些日志记录方法。

ilogger.cs

public interface ILogger
{   
    void LogError(string message, Exception exception = null);

    void LogMessage(string message);

    void LogValidationError(UploadResult uploadResult);

    void LogValidationError(ValidationResult validationResult);

    void LogProcessingError(string processingError);
}

我有一个实现这个接口的 LogHelper 类。LogHelper 类通过 StructureMap 进行实例化,例如

ObjectFactory.Initialize(
    request =>
    {
        request.For<ILogger>().Singleton().Use<LogHelper>();

    });

我有很多类在它们的构造函数中我只是实例化这个类并调用方法来记录信息。例如:我有一个类说 Dummy1 在其构造函数中我将 LogHelper 实例化为:

public Dummy1()
{
    this.logger = ObjectFactory.GetInstance<ILogger>();     
}

在 LogHelper 中,我有一个方法,它基本上创建日志文件并将作为参数传递给它的消息写入。

public void LogMessage(string message)
{
    using (var writer = this.GetTextWriter(this.messageFilename))
    {
        writer.WriteLine(message);
    }
}

目前,文件名被硬编码到 LogHelper 类的常量属性中private string messageFilename = "logs\\UserCreationResult.log"

但是我希望在实例化 LogHelper 时动态发送文件名。我想拥有一个类属性并在实例化类时在构造函数中定义该属性。但是由于 LogHelper 类被实例化为ObjectFactory.GetInstance<ILogger>(). 我无法调用可以传递文件名的构造函数。

斯科特·汉南

不幸的是,你这样做的方式有点弄巧成拙。你的类只知道ILogger,没有任何特定的实现ILogger这很好 - 这意味着实现可以写入文件、SQL 表或任何内容。

但是如果你的类只知道ILogger,而不知道实现,那么你的类怎么知道记录器需要一个文件路径?如果您将方法签名更改ILogger为包含文件路径,则会发生两件事。

  1. 就不可能有任何的实现ILogger写入一个文件(除非它忽略文件路径,这将是很奇怪的。)
  2. 现在调用记录器的类必须知道文件路径。该类将从哪里获取文件路径?它会存储在类中吗?在这种情况下,您最终会得到一个不起作用的类,除非它是在计算机上执行的程序集的一部分,它可以写入该确切的文件路径。

相反,在哪里以及如何记录的细节应该存在于你的ILogger实现中。这更接近单一职责原则。调用的类ILogger不负责有关如何ILogger工作的决定它不知道,也不想知道。上面写着“来,拿这个并记录下来。” 记录器实现负责其余的工作。

我建议ObjectFactory完全取消静态并使用容器来解析和创建您的所有类,包括记录器和依赖于它的类,但这太广泛了,并没有真正的帮助。(它已被弃用,因为它是一个糟糕的模式。它甚至不在 StructureMap 的最新版本中。)

以上都是推荐。在此之后,我提供了一个不是真正值得推荐的选项,但需要较少的更改并使您的类不知道文件路径,因为请永远不要这样做。

一种选择 - 半途而废 - 可能是注册ILogger. 您可以将记录器类修改为如下所示:

public class FileLogger : ILogger
{
    private readonly string _filePath;

    public FileLogger(string filePath)
    {
        _filePath = filePath;
    }
}

现在您可以创建该记录器类的多个实例,向每个实例传递不同的文件路径。这样它就不是静态属性,它限制您只有一个文件路径。

然后你可以像这样注册你的实现。

ObjectFactory.Initialize(
    request =>
    {
        request.For<ILogger>().Singleton()
            .Use<FileLogger>(() => new FileLogger("some path")).Name = "LoggerOne";

        request.For<ILogger>().Singleton()
             .Use<FileLogger>(() => new FileLogger("some other path")).Name = "LoggerTwo";

    });

现在,你的类可以说就是了记录器,就像这样:

var logger = ObjectFactory.GetNamedInstance<ILogger>("LoggerOne");

但请不要真的那样做。这比我在这里可以详细描述的要多,但是看看依赖注入,这样你的类真的只知道ILogger,不知道或不关心他们得到的实现,而不告诉它任何关于如何做它的实现工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何通过类类型委托构造函数的实例化?

来自分类Dev

如何在工厂中为延迟实例化指定具体类/如何延迟构造函数调用

来自分类Dev

如何使用基本构造函数实例化继承的类?

来自分类Dev

如何实例化使用构造函数扩展类的特征

来自分类Dev

构造函数接受参数时如何实例化模板类

来自分类Dev

在该类的构造函数中实例化类变量

来自分类Dev

显式实例化的类模板中的自动构造函数

来自分类Dev

访问在MainWindow()构造函数中实例化的类

来自分类Dev

C#-在构造函数上实例化类的StackOverflowException

来自分类Dev

如何在PHP中实例化具有参数化构造函数的.NET类?

来自分类Dev

如果默认构造函数是超类,则默认构造函数如何实例化对象,而无参数构造函数的主体为空?

来自分类Dev

C++在初始化类实例时隐式调用类成员的构造函数

来自分类Dev

如何使PHP类在其构造函数中实例化另一个类?

来自分类Dev

c ++调用模板构造函数实例化

来自分类Dev

实例化Raku类,并在构造函数中更新实例变量

来自分类Dev

可以在类构造函数中实例化和分配类的数组

来自分类Dev

构造函数执行顺序/顺序:函数中静态变量(类实例)的依赖初始化

来自分类Dev

如何在没有复制构造函数的情况下初始化类的静态实例

来自分类Dev

在C ++中的模板实例化中将带有构造函数的类用作类型参数

来自分类Dev

构造函数中的实例化对象时的C ++类成员作用域

来自分类Dev

C#类和实例构造函数

来自分类Dev

数组实例化调用构造函数吗?

来自分类Dev

数组实例化调用构造函数吗?

来自分类Dev

如何从具体子类中的重写方法访问通过抽象类中的构造函数实例化的对象的属性?

来自分类Dev

Android通过其他类java.lang.InstantiationException中的线程调用函数:无法实例化类……没有空的构造函数

来自分类Dev

类型类实例化中的现有常量(例如,构造函数)

来自分类Dev

依赖注入:在无参数构造函数中实例化具体类时,您会失去什么

来自分类Dev

PHP-在类的构造函数中初始化对象的实例,在静态成员中进行访问

来自分类Dev

C#根据参数类型实例化基础构造函数的派生类

Related 相关文章

  1. 1

    如何通过类类型委托构造函数的实例化?

  2. 2

    如何在工厂中为延迟实例化指定具体类/如何延迟构造函数调用

  3. 3

    如何使用基本构造函数实例化继承的类?

  4. 4

    如何实例化使用构造函数扩展类的特征

  5. 5

    构造函数接受参数时如何实例化模板类

  6. 6

    在该类的构造函数中实例化类变量

  7. 7

    显式实例化的类模板中的自动构造函数

  8. 8

    访问在MainWindow()构造函数中实例化的类

  9. 9

    C#-在构造函数上实例化类的StackOverflowException

  10. 10

    如何在PHP中实例化具有参数化构造函数的.NET类?

  11. 11

    如果默认构造函数是超类,则默认构造函数如何实例化对象,而无参数构造函数的主体为空?

  12. 12

    C++在初始化类实例时隐式调用类成员的构造函数

  13. 13

    如何使PHP类在其构造函数中实例化另一个类?

  14. 14

    c ++调用模板构造函数实例化

  15. 15

    实例化Raku类,并在构造函数中更新实例变量

  16. 16

    可以在类构造函数中实例化和分配类的数组

  17. 17

    构造函数执行顺序/顺序:函数中静态变量(类实例)的依赖初始化

  18. 18

    如何在没有复制构造函数的情况下初始化类的静态实例

  19. 19

    在C ++中的模板实例化中将带有构造函数的类用作类型参数

  20. 20

    构造函数中的实例化对象时的C ++类成员作用域

  21. 21

    C#类和实例构造函数

  22. 22

    数组实例化调用构造函数吗?

  23. 23

    数组实例化调用构造函数吗?

  24. 24

    如何从具体子类中的重写方法访问通过抽象类中的构造函数实例化的对象的属性?

  25. 25

    Android通过其他类java.lang.InstantiationException中的线程调用函数:无法实例化类……没有空的构造函数

  26. 26

    类型类实例化中的现有常量(例如,构造函数)

  27. 27

    依赖注入:在无参数构造函数中实例化具体类时,您会失去什么

  28. 28

    PHP-在类的构造函数中初始化对象的实例,在静态成员中进行访问

  29. 29

    C#根据参数类型实例化基础构造函数的派生类

热门标签

归档