c# - 控制反转和选择

标签 c# inversion-of-control unity-container

我正在尝试正确使用控制反转。我的应用程序运行良好。我使用 Unity 作为 IoC 容器。但是,当可以选择使用哪个具体类时,我认为我出错了。

在这个例子中,我有一个从特定数据源获取数据的类。根据文件类型,我调用数据访问器类。

此服务类检查类型、进行切换,然后选择要使用的具体类。

但是,似乎我在这里通过在类里面“更新”一些东西来打破 IoC 原则。我不再注入(inject)这个服务类,因为在这一点上,我还没有决定我正在使用哪种文件类型。所以我不得不注释掉“注入(inject)”,而是对其进行硬编码。

这是一段代码摘录。

public class DataService : IDataService
    {
        IFileReader _fileReader;
        public DataService(IFileReader fileReader)
        {
            // _fileReader = fileReader;
        }

        /// <summary>
        /// Returns reporting data based on a group of export files.
        /// </summary>
        /// <param name="files">A list of files to analyse</param>
        /// <returns></returns>
        private List<RawFileData> GetRawData(string[] files)
        {
            foreach (var file in files)
            {
                // validate files exists.
                switch (GetFileType(Path.GetFileName(file)))
                {
                    case "CSV":
                         {
                             fileIsOK = true;
                             _fileReader = new CSVileConnector();
                             break;
                         }
                     case "TXT":
                         {
                             fileIsOK = true;
                             _fileReader = new TXTFileConnector();
                             break;
                         }
                     default:
                         break;
                 }
                 if (fileIsOK)
                 {
                     var finedata = _fileReader.ReadData(file);
                     data.Add(new RawFileData
                     {
                         DataItems = finedata,
                         FileName = file
                     });
                }
            }

            return data;
        }

这是处理此类情况的正确方法吗?在创建类(class)时,我不确定要“依赖”哪个子类(class)?然后在逻辑上决定它,并新建正确的 Concrete 类?

最佳答案

一个改进可能是将读者的选择与阅读本身分开——一个名为 IFileReader _getDataReader(string filename) 的私有(private)方法。 .所以在你的 foreach 循环中你说 var reader = _getDataReader(filename); .读者没有充分的理由成为您类(class)中的私有(private)属性(property),因为它不是构造的,可以不断变化,并且其使用范围仅限于 GetRawData。 .您可以考虑通过构造函数注入(inject)的是一个带有 GetDataReader(string) 的类在其接口(interface)定义中。它本身可以拥有私有(private) Dictionary<string, Type>它将以文件扩展名作为键,然后将该文件的读者作为值。如果你愿意,你甚至可以在你的 app.config 中配置它。这就是所谓的 Service Locator模式。

有很好的论据表明 this is actually an anti-pattern由于各种原因。也可能有人会说你想多了——因为你只有两个选择,而且这样阅读很容易——但是将读者的选择与阅读本身分开至少会让你更容易如果需要,可以更改。

关于c# - 控制反转和选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42405147/

相关文章:

c# - Metro 应用程序通过 WCF 服务连接到 SQL - 错误

c# - asp.net OnClientClick 没有为最初禁用的按钮呈现

c# - +/- 登录 TimeSpan 的 ParseExact()?

dependency-injection - 使用 Unity IoC 注册和解析 SignalR 集线器

c# - 使用 Unity 解决通用 Microsoft.Extensions.Logging.ILogger<T> - 获取 InvalidCastException

c# - 使用 Unity 自动注册所有接口(interface)

c# - 输入时移除按钮边框

c# - IoC 范式中的非平凡构造函数是一件坏事吗?

java - 在Web项目中哪里创建了ApplicationContext?

c# - 比 Dictionary<Type, X> 更快的选择?