c# - 在需要时从接口(interface)转换为某个具体类是一种好习惯吗?

标签 c# oop design-patterns dependency-injection simple-injector

我正在开发一个小型系统,我开发了经典的通用存储库。现在,我的 DAL 具有以下架构。

public interface IRepositorio<T> where T : class
{
    T Get(long id);
    long Insert(T obj);
    bool Update(T obj);
    bool Delete(T obj);
}

public abstract class Repositorio<T> : IRepositorio<T> where T : class
{
    public IDbConnection Connection
    {
        get
        {
            return new SqlConnection(ConfigurationManager.ConnectionStrings["DBFila"].ConnectionString);
        }
    }

    public T Get(long id)
    {
        //...
    }

    public long Insert(T obj)
    {
        //...
    }

    public bool Update(T obj)
    {
        //...
    }

    public bool Delete(T obj)
    {
        //...
    }
}

我的具体存储库如下所示:

public class FilaRepositorio : Repositorio<FilaRepositorio>
{
    public FilaRepositorio() 
    {
    }

    public void SomeCustomMethod()
    {
        // Some custom method
    }
}

我还使用简单注入(inject)器来遵循 IoC 和 DI 模式,因此,当我尝试调用“SomeCustomMethod()”时,我无法访问它(很明显)。看:

public class Processador
{
    private IRepositorio<FilaModel> _repoFila;
    public Processador(IRepositorio<FilaModel> repoFila)
    {
        _repoFila = repoFila;
    }

    public void Processar()
    {
        _repoFila.SomeCustomMethod(); // <-- wrong

        ((FilaRepositorio)_repoFila).SomeCustomMethod();// <-- works
    }
}

鉴于此我有一些问题:

  • 进行该转换 (FilaRepositorio) 是一种好的做法还是可以接受的做法?
  • 如果这不是一个好的做法,如何为这种情况编写好的代码?

最佳答案

有几个选项可用。进行类型转换的主要问题是它是一个实现问题。

如果注入(inject)的对象不是 FilaRepositorio 会发生什么?

通过进行强制转换,您将类与一个实现关注点紧密耦合,但不能保证是注入(inject)依赖项。因此,构造函数对于执行其功能所需的内容并不完全真实。

这证明需要练习Explicit Dependencies Principle

The Explicit Dependencies Principle states:

Methods and classes should explicitly require (typically through method parameters or constructor parameters) any collaborating objects they need in order to function correctly.

避免这种情况的一种方法是制作一个派生接口(interface),该接口(interface)显式公开其依赖项的所需功能。

public interface IFilaRepositorio : IRepositorio<FilaModel> {
    void SomeCustomMethod();
}

public class FilaRepositorio : Repositorio<FilaModel>, IFilaRepositorio {
    public void SomeCustomMethod() {
        //...other code removed for brevity.
    }
}

并让 Processador 依赖于更有针对性的抽象。

现在根本不需要强制转换,类明确表达了它需要什么。

public class Processador {
    private readonly IFilaRepositorio _repoFila;

    public Processador(IFilaRepositorio  repoFila) {
        _repoFila = repoFila;
    }

    public void Processar() {
        _repoFila.SomeCustomMethod(); // <-- works
    }
}

关于c# - 在需要时从接口(interface)转换为某个具体类是一种好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44446005/

相关文章:

oop - 似乎无法完全理解 textInput 如何在 super 简单的网站上工作

javascript - 如何从构造函数返回单个数组项

java - 在面向对象编程中获取特定类的所有对象

php - 用于将一种数据格式转换为另一种数据格式的 OOP 模式

c# - 从 C# 中的列表中选择唯一元素

c# - WebException 响应属性返回 null

oop - 这个反模式的名字是什么?方法签名是个骗子

c++ - 用 C++ 编写我自己的类似 STL 的迭代器的实现

c# - BusyIndi​​cator 允许两次触发 RelayCommand

c# - VS2010 : Code analysis warning CA2000. 对象未沿所有异常路径进行处理