簡體   English   中英

是否有合適的設計模式來重構此C#代碼

[英]Is there a suitable design pattern to refactor this C# code

我有2個不同的第三方程序集,它們為業務服務提供相同的API,並使用相同的類名(〜40個類/類型/擴展名),但位於不同的程序集中:

    Company.Assemply.V1
    Company.Assemply.V2

我在項目中引用了兩個程序集。

這些程序集沒有通用的接口,第三者也無法提供通用的接口

因此,C#編譯器將兩個程序集中的每種類型都視為不同的類型。

我想為每個程序集實現一個類Myservice ,以支持兩個版本V1 / V2。

我使用以下代碼實現Myservice.V1.Myclass

    //#define V1

    #if V1
       using  Company.Assemply.V1;
    #else
       using  Company.Assemply.V2;
    #endif

    #if V1
      namespace Myservice.V1
    #else
      namespace Myservice.V2
    #endif
    {
       //my implementation that use all classes /types in any v1/v2 assembly
        class MyClass {.... }
     }

然后我將相同的代碼復制並粘貼到其他c#文件MyClassV2.cs (約400行)中,以獲得Myservice.V2.Myclass並取消注釋編譯器標志#define V1

我不能使用泛型

        MyClass  <T> where T:??

因為T沒有通用接口

這兩個班都很好。

問題是維護v1時,我必須將代碼復制/粘貼到其他文件MyClassV2.cs並取消注釋編譯器標志#define V1以支持V2。

有沒有更好的方法/合適的設計模式/重構技術可以解決此類問題。 我想使用/維護一個代碼庫,並避免對其他類版本進行復制/粘貼。

給我一個重構以上代碼的例子。

一種選擇是使用適配器模式 ,這是將抽象添加到不使用它們的BCL和第三方代碼的一種常見方法。 例如,您在第三方程序集中有一個名為MyClass的類型,並且V1V2共享相同的成員:

public interface IMyClass
{
    // All members of MyClass 
    // (except we have a special case for DoSomething() because it
    // has a return type SomeType we also need to adapt to ISomeType).

    ISomeType DoSomething();
}

public class MyClassV1 : V1.MyClass, IMyClass
{
    // No need to re-implement members (base class satisfies interface)
    // However, if there are return parameters, you will need to 
    // also use a decorator pattern to wrap them in another adapter.

    public override ISomeType DoSomething()
    {
        return new SomeTypeV1(base.DoSomething());
    }

}

public class MyClassV2 : V2.MyClass, IMyClass
{
}

public interface ISomeType
{
     // All members of SomeType
}

public class SomeTypeV1 : ISomeType
{
    private readonly SomeType someType;

    public SomeType(SomeType someType)
    {
        this.someType = someType;
    }

    // re-implement all members and cascade the call to someType
}

然后,您可以在應用程序中使用IMyClass ,使用DI注入所需的任何一個。

public class HomeController : Controller
{
    private readonly IMyClass myClass;

    public HomeController(IMyClass myClass)
    {
        this.myClass = myClass
    }
}

如果您需要在運行時在實現之間進行切換,請考慮策略模式

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM