我正在开发一个小型系统,我开发了经典的通用存储库。现在,我的 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/