.net - 泛型和松耦合 : Can Class<T> be decoupled without type assumptions?

标签 .net generics reflection dependency-injection loose-coupling

我一直在尝试松散耦合我的数据访问层。我发现依赖注入(inject)过程非常有帮助,但在考虑使用泛型时遇到了一些难题。

有没有办法让支持泛型类型参数的类真正实现解耦和类型安全?我担心的是,即使您编写一个公共(public)接口(interface),如果后续的派生类型与您最初编码的实体不同,那么您可能会遇到一些编译器可能无法捕获的令人讨厌的运行时错误。

问题是,当我编写代码从数据库获取数据并水化我的对象时,当我尝试在下一层实现它时,我遇到了一个难题。如果我传入下面的 Foo2 这样的类,我可能会破坏我的代码,因为没有“隐式”转换。我一直在使用反射来尝试放松一些事情,但我不断回到这个问题,即当从数据库获取数据时,我需要水合具体类型。然后,该类型会产生类型转换和类型保证方面的问题。此外,如果我想抽象实体库中所有多种类型的所有方法,我可以通过反射来完成此操作,但我仍然遇到这样的问题:泛型只能在显式“where T : ISomeInterface”语句上进行类型保证。最后,如果我们有更多的派生类型或从接口(interface)分支形成新类型的类型,这个模型就会崩溃。认为我需要为每种类型实现新的数据访问对象将迫使数据访问层发生变化。这打破了我心目中松散耦合的定义。

所有这些似乎迫使我回到这个问题 - 泛型可以以真正松散耦合的方式使用吗?如果是这样,您可以提供哪些引用?

简化示例:

public interface IEntity
{
    // stuff for state and methods ...
}
public interface IRepository<T> where T : IEntity
{
    void Save(out int id, T obj);
    T Load(int id);
}
public interface IFoo : IEntity
{
    int Id { get; set; }
    //All other IEntities goodness
    //Some new goodness specific to Foo
}
//Concrete Entities:
public class Foo : IFoo
{
    // blah blah
}
public class Foo2 : IFoo
{
    // new blah blah
}

public class FooRepository : IRepository<Foo> //OOPS, Looks like we have settled in on a concrete type!
{

    public void Save(out int id, Foo obj)
    {
        // ADO.NET code to access Sql ...
        id = 1;// this would actually be the result of the Sql insert output parameter
        return;
    }

    public Foo Load(int id)
    {
        Foo foo = new Foo();
        // ADO.Net code to access Sql
        return foo;
    }
}

那么,您将如何处理可以处理任何 IFoo 派生对象的代码,并且无论程序员接下来做什么,仍然能够返回完全形成的具体类型?最好放弃通用部分并坚持依赖注入(inject)吗?任何引用、指导等都会很棒。

最佳答案

对于您在这里遇到的问题,您始终可以使用 typeof (或者可能是不同的运算符/方法)来获取对象的动态类型。这样,您始终可以在遇到某些转换错误之前执行检查。

您可以为顶级类型设置具体类型限制,但这确实违背了泛型的目的。

否则,我真的不知道如何解决你的问题。如果您使用泛型,重点是添加松散耦合和与类型无关的泛型操作。检索它的唯一方法是 typeof 然后重新类型转换,捕获边缘情况以防止类型转换错误。关于您的问题:

Can generics be used in a truly loose coupled way?

不太明白你的意思?从你的问题的语义上看,你当然可以。这实际上是泛型的目的之一。

So how would you deal with code that could handle any IFoo derived object and still be able to return a fully formed concrete type regardless of what programmers do down the road?

这也很模糊。我可以写:

public SomeType method(IFoo obj)
{
...
}

这仍然可以处理任何 IFoo。为此,您不需要泛型。如果你想返回具体传入的类型,那么:

public T method<T>(IFoo obj) where T:IFoo
{
    return (T)obj;
}

希望这有帮助。如果我弄错了,LMK。

关于.net - 泛型和松耦合 : Can Class<T> be decoupled without type assumptions?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15373849/

相关文章:

.NET - 启用 UAC (Windows7/Vista) 时,应用程序如何能够 self 更新?

c - 你怎么能对没有反射的编程语言感到厌烦呢?

c# - 在 C# 中检查一个 VB.NET 对象是否为 null 会产生意外的编译错误

.net - 与 SMO 连接共享交易

.net - MemoryStream 必须明确处理?

xcode - Swift:是否可以为 UIViewController 使用通用和 Storyboard

c# - 逆变和运算符重载

c# - 为什么 Array 不是泛型类型?

java.security.AccessControlException : access denied using Java Web Start

c# - 通过反射将对象附加到 IEnumerable<>