C# 依赖注入,don';我不知道在哪里放置方法

C# 依赖注入,don';我不知道在哪里放置方法,c#,dependency-injection,interface,C#,Dependency Injection,Interface,我创建了一个ILogger接口和一个实现ILogger的ListViewLogger类,现在ILogger有一个方法(SetListViewReference)不应该在那里,因为不是所有的记录器都会登录到一个ListView,我不知道放在哪里,因为我正在做依赖注入,所以我需要这个方法,那么我应该怎么做呢?谢谢 using System; using System.Windows.Forms; namespace AutoTweet { public interface ILogger

我创建了一个
ILogger
接口和一个实现
ILogger
ListViewLogger
类,现在
ILogger
有一个方法(
SetListViewReference
)不应该在那里,因为不是所有的记录器都会登录到一个ListView,我不知道放在哪里,因为我正在做依赖注入,所以我需要这个方法,那么我应该怎么做呢?谢谢

using System;
using System.Windows.Forms;

namespace AutoTweet
{
    public interface ILogger
    {
        void Log(string text);

        void SetListViewReference(ListView listview);
    }

    public class ListViewLogger : ILogger
    {
        private ListView _lvLog;

        public void Log(string text)
        {
            _lvLog?.Items.Add(makeLvi(text));
        }

        public void SetListViewReference(ListView listview)
        {
            _lvLog = listview;
        }

        private ListViewItem makeLvi(string text)
        {
            ListViewItem ret = new ListViewItem { Text = DateTime.Now.ToString() };
            ret.SubItems.Add(text);
            return ret;
        }
    }
}

有一个新的
IListViewLogger
接口,该接口将继承自
ILogger
,并具有该附加方法:

public interface ILogger
{
    void Log(string text);
}

public interface IListViewLogger : ILogger
{
    void SetListViewReference(ListView listview);
}

public class ListViewLogger : IListViewLogger
{
    //...
}
不过,设计实际上取决于ListView的范围


如果应用程序中只有一个ListView,那么应该在composition根目录中的某个位置设置它,因为您知道记录器的具体类型,所以可以在该位置设置它。如果作用域是每个视图,那么拥有这个扩展界面就很好了,因为您需要以某种方式告诉记录器它应该登录到哪里。

如果您想从
ILogger
界面中删除对UI控件的依赖,您可以应用它。一种方法是将
事件
添加到接口。为简单起见,我将不介绍另一个接口,即:

接口ILogger
{
无效日志(字符串msg);
事件行动日志信息;
}
类发布者日志:ILogger
{
公共事件操作日志消息=(msg)=>{};
公共无效日志(字符串msg)
{
控制台写入线(msg);
日志信息(msg);
}
}
然后在
窗体中使用它
控件:

public Form1()
{        
初始化组件();
var publisherLogger=new publisherLogger();//或注入它
publisherLogger.LogMessages+=msg=>
{
//将消息添加到列表视图
ListViewItem=new ListViewItem{Text=DateTime.Now.ToString()};
项目。子项目。添加(文本);
_listView.Items.Add(ret);
};
}
您还可以将附加在
ListView
LogMessage
的设置代码提取到扩展方法中,以使事情更加干涸


旁注:

该方法看起来像是
listviewlogger
@miparnisari的构造函数。我曾考虑过从构造函数接受listview引用,但我不能接受,因为DI,我没有listview的范围。接口应该存在,以支持客户端需求。客户端何时需要调用
SetListViewReference
?@MarkSeemann我的ListViewLogger类如何记录应用程序中发生的事件而不引用ListView?。。。让它自己创建它,或者通过它的构造函数注入它。。。在一个平行的注释中,请考虑这一点:哈哈!这正是我在问这个问题之前所想的,但是这会破坏DI的全部目的,因为不是所有的记录器都会实现IListViewLogger。我的Form1 ctor需要接受实现ILogger的所有类型的记录器,因此我不能让我的Form1 ctor接受IListViewLogger。如果我要登录到控制台,我不会在这里寻求帮助,因为这很简单,但我想登录到ListView,并且ListView是Form1的一部分。也许您可以修改您的解决方案以支持外部列表视图。@user1803300我已经更新了代码示例。如果仍然不符合您的期望,请相应地更新问题,并提供一个示例,说明您希望如何在自定义
表单中使用记录器。我看到了您的编辑,看起来您是从Form1类进行日志记录的,我不希望这样,我只需要一次调用ListViewLogger.Log()让ListViewLogger帮我处理所有这些。@user1803300现在我更不明白你想要什么。
ListViewLogger.Log()
应该做什么?我刚刚说明了我想用什么方法来处理所有逻辑,显然它(在表单1中)会被称为像_lvLogger.Log()。(其中_lvLogger是声明为ILogger的私有只读字段)