2016-07-27 22 views
-2

我正在開發一個處理來自第三方.NET API的對象的應用程序。處理器通過實現以下IProcessor接口來創建。將依賴於第三方API的類的部分分離爲單獨的程序集

public interface IProcessor 
{ 
    Process(ApiClass input); 
} 

該接口的具體實現還可以添加其他屬性來控制特定處理器的工作方式。例如...

public class ProcessorA : IProcessor 
{ 
    public double X; 
    public double Y; 

    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

public class ProcessorB : IProcessor 
{ 
    public string MyParameter; 
    public string MyOtherParameter; 

    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

第三方API和ApiClass只能從本地應用程序中的功能。但是,我希望能夠創建其他能夠讀寫處理器的.NET程序集,但不需要引用第三方API。具體而言,我希望能夠將處理器序列化爲/從JSON反序列化。

因此,我試圖確定將處理器的參數及其實現IProcessor.Process()拆分爲兩個獨立程序集的最佳方法。一個引用第三方API,另一個不引用。

一種選擇是製作對象的重複代理版本。

//In assembly that does NOT reference 3rd party API 
public class ProcessorAProxy 
{ 
    public double X; 
    public double Y; 
} 

//In assembly that references 3rd party API 
public class ProcessorA 
{ 
    public double X; 
    public double Y; 

    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

但是,這將要求我保持這些類之間的屬性同步。我還必須編寫映射代碼來在它們之間進行轉換。

另一種選擇是將參數存儲在代理類中,然後創建一個繼承此類的類,該類添加了Process()方法。

//In assembly that does NOT reference 3rd party API 
public class ProcessorA 
{ 
    public double X; 
    public double Y; 
} 

//In assembly that references 3rd party API 
public class ProcessorA : ProcessorAProxy 
{ 
    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

此選項不再具有需要保持同步的重複屬性。然而,如果我反序列化了一個ProcessorAProxy,我不知道如何將其轉換爲實際的ProcessorA,而無需再次處理映射值。

替代繼承類我也可以將選項注入到實際通過其構造函數進行處理的類中。

//In assembly that does NOT reference 3rd party API 
public class ProcessorAOptions: IOptions 
{ 
    public double X; 
    public double Y; 
} 

//In assembly that references 3rd party API 
public class ProcessorA : IProcessor 
{ 
    public ProcessorAOptions Options; 

    public ProcessorA(ProcessorAOptions opt) 
    { 
     Options = opt; 
    } 

    public Process(ApiClass input) 
    { 
     //Code here... 
    } 
} 

那麼我會反序列化特定類型的IOptions,然後將需要獲得通過正確的具體類型的IProcessor的構造。這可以通過ProcessorFactory來處理。

IOptions options = serializer.Read(); //Read the some options 
ProcessorFactory fact = new ProcessorFactory(); //Create a factory 
IProcessor proc = fact.GetProcessor(options); //Get the processor for options from the factory 

到目前爲止,我喜歡這個選項最好的,但我不知道該ProcessorFactory從一個特定類型的IOptions映射到正確的IProcessor類型的最佳方式。

一種選擇是創建一個巨大的if語句來檢查每個選項類型。

這可行,但似乎有點低效,特別是如果我有很多處理器類型。

另一種選擇是使用約定和反思。例如找到一個實現了IProcessor的類,並有一個構造函數,它將具體的IOptions類型作爲參數。或者找到一個名稱與刪除了「選項」後綴的選項類名稱相同的類(ProcessorBOptions - > ProcessorB)。

使用反射有更好的選擇嗎?總的來說,是否有更好的方法來將引用第三方API的代碼和不包含在單獨程序集中的類中的代碼分離開來,這些代碼是如何映射到另一個的?

回答

0

您的最後一種方法與WebRequest在CLR中的工作方式類似。您將Uri傳遞給Create,並返回正確的子類。

https://msdn.microsoft.com/en-us/library/system.net.webrequest(v=vs.110).aspx

如果你看一下WebRequest.Create參考源,你可以通過一些微軟採用的模式運行:

http://referencesource.microsoft.com/#System/net/System/Net/WebRequest.cs,117

http://referencesource.microsoft.com/#System/net/System/Net/Internal.cs,1608

一般來說,把它歸結爲從內部查找中挑選類型的名稱,並使用Activator.CreateInstance返回正確的派生類型。

https://msdn.microsoft.com/en-us/library/system.activator.createinstance(v=vs.110).aspx

相關問題