静态存储库......不能使用DI,该怎么办?

时间:2010-08-21 20:05:49

标签: c# dependency-injection inversion-of-control static-methods nopcommerce

我处于需要修改第三方开源应用程序(NopCommerce)中静态存储库返回内容的情况。问题是他们使用静态存储库,所以我不能仅仅继承接口和DI我自己的存储库。我试图这样做而不修改NopCommerce代码库......任何新鲜的想法?

编辑:我希望NopCommerce使用我的回购,而不是让我的代码使用他们的回购。

3 个答案:

答案 0 :(得分:3)

您可以通过创建自己的接口和委托给NopCommerce的类实现来抽象出他们的东西。然后让您的代码使用界面而不是直接访问NopCommerce的类。在将结果返回给应用程序之前,您可以在类中修改NopCommerce的输出。

作为额外的奖励,你还可以模拟界面来做一些不需要完整的存储库实现的测试。

这样的东西,在代码中:

public interface IRepository 
{
   MyItem GetItem(int id);
}

public class MyNopCommerceWrapper : IRepository
{
   public MyItem GetItem(int id)
   {
       // I have no idea what NopCommerce API looks like, so I made this up.
       var myItem = NopCommerce.GetItem(id);

       ModifyMyItem(myItem);

       return myItem;
   }
}

答案 1 :(得分:3)

我们目前处于一个非常非常紧迫的截止日期,这个问题并非如此。所以我想首先从一个穷人的静态界面/穷人的DI开始,如下所示(所以我不必修改整个解决方案)。然后在稍后的时间,当我们没有时间紧迫时,转换为使用接口和依赖注入并向NopCommerce提交补丁:

// Poor-man's static interface (DI).
public static class OriginalBuiltInStaticClass {
    private static IMyNewClass _myNewClass;

    public static void Inject(IMyNewClass myNewClass) {
        _myNewClass = myNewClass;
        A = _myNewClass.A;
        B = _myNewClass.B;
        C = _myNewClass.C;
    }

    public static Action A = CopySimpleRenameBuiltInStaticClass.A;
    public static Func<int, string> B = CopySimpleRenameBuiltInStaticClass.B;
    public static Action C = CopySimpleRenameBuiltInStaticClass.C;
}

// Original vendor class which was copied and renamed.
public static class CopySimpleRenameBuiltInStaticClass {
    public static void A() {
        Console.WriteLine("OriginalBuiltInStaticClass.A()");
    }

    public static string B(int id) {
        Console.WriteLine("OriginalBuiltInStaticClass.B()");
        return id.ToString();
    }

    public static void C() {
        Console.WriteLine("OriginalBuiltInStaticClass.C()");
    }
}

// Creating an interface to merge into trunk of NopCommerce (convert static repositories)
public interface IMyNewClass {
    void A();
    string B(int id);
    void C();
}

// Implementation of interface.
public class MyNewClass : IMyNewClass {
    public void A() {
        Console.WriteLine("MyNewClass.A()");
    }

    public string B(int id) {
        Console.WriteLine("MyNewClass.B()");
        return id.ToString();
    }

    public void C() {
        CopySimpleRenameBuiltInStaticClass.C();
    }

}

有什么想法吗?

答案 2 :(得分:2)

听起来像是Facade的工作。