C#依赖注入 - 如何注入无源的依赖关系?

C#依赖注入 - 如何注入无源的依赖关系?

问题描述:

我想开始使用C#的一些简单的依赖注入,我碰到一个问题,我似乎无法拿出答案。C#依赖注入 - 如何注入无源的依赖关系?

我有一门课是由另一个部门编写的,我没有在我的项目中有源代码。我想通过一个使用接口的构造函数来注入这种类型的对象,但是当然,我不能改变注入对象的实现来实现接口来在将对象强制转换为接口类型时实现多态。

我见过的这个技术的每一个学术例子都有类使用在项目中声明的类。如果没有源代码在项目中可用,我将如何去注入我的依赖项?

我希望有道理,谢谢。

如果您不需要更改课程中的任何内容,则几乎不需要代码。让我们假设你在一个DLL中有一个类X,你希望将它注入到你正在编写的另一个类Y中。在这种情况下,你可以创建X的实例,并把作为参数Y.这样的构造会是这个样子:

添加到含X类项目中的DLL的引用。

Use NameSpaceOfX; 
Class Y 
{ 
    Public Y() //Default constructor 
    { 
    } 

    Public Y(X instanceOfX) 
    { 
     //Use instanceOfX here as required 
    } 
} 

在你的主代码:

//Create instance of X 
X instanceOfX = new X(); 
//Inject it into Y 
Y instanceOfY = new Y(instanceOfX); 
//Use Y now. 

你可以创建一个在你的目标类型的包装,因此,例如,你可以有一类,他们提供:

public class TheirClass 
{ 
    public void DoSomething(); 
} 

与哪些你可以定义一个接口:

public interface ITheirClass 
{ 
    void DoSomething(); 
} 

和实施一个包装类,接口:

public class TheirClassWrapper : TheirClass, ITheirClass 
{ 

} 

或者,如果他们提供的类是密封的,你需要做的略有不同:

public class TheirClassWrapper : ITheirClass 
{ 
    private TheirClass instance = new TheirClass(); 

    public void DoSomething() 
    { 
    instance.DoSomething(); 
    } 
} 

然后你可以注入该接口来代替。

我知道在MEF我们可以出口的具体类型,让他们正确地注射,但我不知道其他IoC容器。

+0

这正是我在想什么。 – Steven 2010-06-17 07:37:12

+0

适配器模式。好决定。 – Wix 2010-10-18 12:55:19

问题是,你为什么要注入它作为一个接口?是因为类实现了一些你想要抽象出来的属性/方法,所以它可以被替代,或者你只是试图“强制”一个标记接口,因为“我们总是依赖于接口,而不是具体的类” ?如果是后者,那么你就走错了路,因为无论如何你都可能立即将它投射到混凝土中。

假设前两个我可以看到两个选项:

  1. 使用继承来代替。这可能或不可能取决于已创建的类,但是您可以继承它并用新类替换旧类。
  2. 您自己创建接口,使用您需要的方法/属性,并将外部具体类包装在实现接口的类中。

对于第二种情况,如果你不能继承,作为一个例子,假设你只关心一个方法的类(我们称之为方法1())创建一个匹配的接口它:

public interface IMyNewInterface 
{ 
    void Method1(); 
} 

然后创建它的实现,需要具体类的依赖关系(由您作为普通的容器注入)只是调用具体类:

public class MyNewClass : IMyNewInterface 
{ 
    private MyConcreteClass _MyConcreteClass; 

    public void MyNewClass(MyConcreteClass concreteClass) 
    { 
     _MyConcreteClass = concreteClass; 
    } 

    public void Method1() 
    { 
     _MyConcreteClass.Method1(); 
    } 
} 
+0

但是对于这两个选项中的后者,可以单元测试你自己的类,它使用第三方类作为传递给构造函数的参数。即有可能用ITheirClass嘲笑他们的类别 – 2010-06-17 07:49:54

+0

这两个选项都可以让你替换他们的类别(泛型除外),但接口方法将是我的偏好。 – 2010-06-17 08:23:06

+0

对不起,我不是指选项1和2.是指“..我总是依赖...”的报价。也许我误读了。也许你的意思是说它不应该只是为了完成而完成的。但好的做法意味着我们为未来的变化或维护铺平道路。如果课堂被注入,那么它会使注入更容易,例如aop性能测量。 – 2010-06-17 08:38:14