将接口映射到未实现接口的类(动态)C#

3

这是我在Stackoverflow上的第一篇帖子。感谢Stackoverflow。

我的问题:

我在类库中有一个接口。

namespace TestClient
{
   public interface IMobileStore
   {
        List<string> GetMobileDetails();

        int AddMobile(string mobile);
   }
}

我在另一个类库中有一个名为MobileLibrary的类,并实现了IMobileStore接口(在开发过程中)。

namespace MobileLibrary
{
    public class MobileLibrary  : IMobileStore
    {
        List<string> GetMobileDetails()
        {
             return new List<string>();
        }

        int AddMobile(string mobile)
        {
             return 1;
        }
    }
 }

我已经在控制台应用程序中使用了MobileLibrary库。

但现在我想使用IndianMobileLibrary(它具有与MobileLibrary类相同的结构,但没有实现接口)来替换MobileLibrary。

注意:IndianMobileLibrary可在另一个类库中使用(无法控制该库 - 第三方库)。

namespace IndianMobileLibrary 
{
     public class IndianMobileLibrary  //(doesn't implement the interface)
    {
         List<string> GetMobileDetails()
         {
             return new List<string>();
         }

         int AddMobile(string mobile)
         {
             return 1;
         }
     }
 }

这里介绍如何动态地将IMobileStore映射到IndianMobileLibrary(作为实现),并动态创建实现IndianMobileLibrary类的IMobileStore对象。
据我所知,企业库依赖注入可以帮助实现这一点。但是我还没有使用过企业库。您能否分享一下此方面的想法?

你有一只不是鸭子的东西,但你想把它变成鸭子? - lordkain
1
请查看此处:http://www.codeproject.com/Articles/597854/Duck-Typing-with-the-Dynamic-Keyword - Mike Cheel
3个回答

2

您应该对强大的即兴接口库(可以通过nuget获得)感兴趣。 通过它的帮助,您可以轻松地完成类似于:

var indian = new IndianMobileLibrary();
IMobileStore iface = indian.ActLike<IMobileStore>();
var mobile = iface.AddMobile("test");

当然,你可以充分利用智能感知功能来处理ActLike返回的对象类型。另一个神奇的优势在于,你根本不需要知道indian的类型。


@Konrad,感谢您的支持...我已经尝试从上面的链接下载即兴接口二进制文件。但是我没有得到dll。您能否分享一下(逐步)链接,以便我可以获取适用于我的项目的正确dll的方法。 - user3794983
我已经安装了即兴接口二进制文件,您能否给出一些想法,如何在不使用印度类型的情况下完成上述操作,因为我事先不知道类型。 - user3794983
@user3794983,只需添加对此dll的引用,添加using ImpromptuInterface;并调用yourObject.ActLike<IMobileStore>()以获取IMobileStore引用。 - Konrad Kokosa

1
最简单的解决方案是采用简单的“代理”样式来包装未实现接口的类,只需使用适配器即可。
public class MyIndianMobileLibrary:IMobileStore
    {
         public MyIndianMobileLibrary(IndianMobileLibrary indian){
          _indianMobileLibrary = indian;
         }
         IndianMobileLibrary _indianMobileLibrary;


         public List<string> GetMobileDetails()
         {
             return indian.GetMobileDetails();
         }

         public int AddMobile(string mobile)
         {
             return indian.AddMobile(mobile);
         }
     }

    public class IndianMobileLibrary  //(doesn't implement the interface)
        {
             public List<string> GetMobileDetails()
             {
                 return new List<string>();
             }

             public int AddMobile(string mobile)
             {
                 return 1;
             }
         }

编辑

这个解决方案很简单,但其实并不是必需的,也许这样可以解决问题:

     public class MyIndianMobileLibrary:IndianMobileLibrary,IMobileStore 
    {
         public MyIndianMobileLibrary(){

         }

         public List<string> GetMobileDetails()
         {
             return base.GetMobileDetails();
         }

         public int AddMobile(string mobile)
         {
             return base.AddMobile(mobile);
         }
     }

@lordkain 你为什么认为这很有趣?这是标准的代理/适配器模式在实践中的应用。 - trailmax
简单而优雅的解决方案,我之前想得太复杂了。 - lordkain
事实上,我之前并不知道IndianMobileLibrary这个类的名称。一些第三方供应商正在同时开发IndianMobileLibrary的功能。我已经为开发编写了一个模拟项目,而在暂存阶段,他们提供了原始的dll文件。之前我只知道/同意函数签名 - user3794983
@user3794983,我建议使用我的解决方案。 - Konrad Kokosa
这太过于复杂了,在大型项目中这是行不通的。你会花更多的时间编写包装器而不是实际的代码。 - Daniel Lobo

0
最简单的方法是创建一个代理来处理IndianMobileLibrary的功能。您可以创建一个代理类,该类实现IMobileInterface接口,但使用IndianMobileLibrary的实现。

使用IndianMobileLibrary;

namespace MyIndianMobileLibrary 
{
    public class MyIndianMobileLibraryImpl : IMobileStore
    {
        List<string> GetMobileDetails()
        {
             return new IndianMobileLibrary.GetMobileDetails();
        }

        int AddMobile(string mobile)
        {
             return 1;
        }
}

现在您有一个可编译的类来实现您的逻辑,并且可以注入到任何调用IMobileStore的地方。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接