2016-05-13 89 views
1

我有一个客户端,库和接口作为中间层的应用程序。库中的类实现Interface.I想调用库而不必引用它。所以我不必这样做:如何仅使用接口创建类的实例

IInterface myClass = new Library.MyClass(); 

一种方法是使用统一我猜。有没有其他方法?不知何故,界面的整个想法现在消失。

谢谢

+0

你在“我想打电话给图书馆而不必引用它”下的含义是什么? – SeM

+0

那么接口就是出于这个原因。客户端不应该打扰Library1,Library2,Library3。如果我要直接调用图书馆的新实例,那么我将失去接口的目的。 – sis

回答

1

有几种方法可以做到这一点。 一,通过使用依赖倒置,如你用Unity展示的那样,另一种是通过编写类工厂,最后如你所述,创建类实例,这根本没有什么帮助:)

我个人的口味倾向于依赖倒置,其中Structuremap是我最喜欢的IoC容器。非常容易设置,并且非常易于使用,但大多数IoC容器都有很好的文档记录。

你通常最终的事情是对的东西的喜欢:

IInterface myClass = myContainer.GetInstanceOf<IInterface>(); 
+0

dosnt此请求者的参考? – Thorarins

+0

不是直接。大多数容器允许您加载所有包含实现的DLL,然后他们可以将接口自行解析为实现。因此,对于IoC的配置,您通常只需告诉容器添加此dll和该dll,容器完成剩下的工作。 –

+0

所以容器做的正是我回答然后.... :) – Thorarins

1

如果我是正确的,该库是不是一个第三方组件,你可以改变的实现!?如果是这样,我会建议使用MEF。它是.Net框架的一部分,并且完全支持你想要的 - 从其他不需要引用的组件中加载组件。

在库中,你必须声明类使用在你应用程式与出口属性:

[Import(typeof(IInterface))] public IInterface myClase; 

[Export(typeof(IInterface))] class MyClass : IInterface{ } 

而在你的客户端应用程序,你可以导入组件

最后你可以编写所有的进口和出口:

var catalog = new AggregateCatalog(); 

// add assamby by type 
catalog.Catalogs.Add(new AssemblyCatalog(typeof (AnyType).Assembly)); 

// add assembly by path 
// this example adds all assembly in the current directory that ends with "Extension.dll". 
catalog.Catalogs.Add(new DirectoryCatalog(@".", "*Extensions.dll")); 
var container = new CompositionContainer(catalog); 

// compose parts: MEF composes all imports and exports 
container.ComposeParts(this); 
1

它通常是做b y使用Factory设计模式。

public interface IMyInterface 
{ 
} 

public class A : IMyInterface 
{ 
    internal A() // so, the user/developer won't be able to call "var a = new A()" outside of the scope of the assembly 
    { 
    } 
} 

public class B : IMyInterface 
{ 
    internal B() 
    { 
    } 
} 

public static class MyFactory 
{ 
    public static IMyInterface CreateA() 
    { 
     return new A(); 
    } 

    public static IMyInterface CreateB() 
    { 
     return new B(); 
    } 
} 

用法:

static void Main() 
{ 
    IMyInterface a = MyFactory.CreateA(); // instance of A 
    IMyInterface b = MyFactory.CreateB(); // instance of B 
} 

如果要创建一个API,你可以设置AB内部构造,因此开发商将不能没有创建它们的实例使用工厂。

注意:您可以使用工厂来存储创建的实例,因此它将返回相同的实例,而不是每次创建一个新的实例。

+0

谢谢你的例子,这是非常有益的!我已经接受了佩德罗的回答,因为它提供了更多的选项来处理这个问题。 – sis

+1

很高兴能帮到你!这个答案从依赖注入的角度来完成工作,而我的是一个设计模式,所以他们可以同时工作 - 特别是如果你也在创建API。对于这个问题,这个答案更好。 :) – KAI