1 回答

TA貢獻1946條經驗 獲得超4個贊
IMO 使用工廠確實是錯誤的方法。Factory 使消費者復雜化,IDependency并且引入這個 Factory 抽象可能會導致整個應用程序發生徹底的變化。
相反,我認為最合適的解決方案是應用代理模式。此代理將是 的一個實現,IDependency它將包裝這兩個IDependency實現,并將根據您指定的條件將任何傳入調用分派到正確的實現。
例如:
public class DependencyDispatcher : IDependency
{
private ImplA a;
private ImplB b;
public DependencyDispatcher(ImplA a, ImplB b) {
this.a = a;
this.b = b;
}
private IDependency Dependency => someCondition ? this.a : this.b;
// Implement IDependency methods to forward the call to Dependency
void IDependency.DoSomething() => this.Dependency.DoSomething();
}
您可以將此代理配置為第三個應用程序IDependency的組合根中的默認實現。
您的更新使事情變得更加清晰。您正在為請求提供一些運行時值,您需要根據此值做出決定。
這里有幾個解決方案。首先,嘗試將此決定從請求正文中移到請求標頭中。這樣,您的調度員可以執行以下操作:
private IDependency Dependency =>
HttpContext.Current.Headers["MyHeader"] == "something" ? this.a : this.b;
如果這不是一個選項,并且信息屬于請求正文,您也許可以讓您的調度員根據其輸入做出決定。例如:
public class DependencyDispatcher : IDependency
{
...
private IDependency GetDependency(string appType) =>
appType == "a" ? this.a : this.b;
void IDependency.DoSomething(DoSomethingData data) =>
this.GetDependency(data.AppType).DoSomething(data);
}
這顯然只有在將該AppType值(或可以轉換為它的值)提供給IDependency的方法時才有可能。只有在這種情況下,有足夠的可用信息才能做出此決定。
如果這不是一個選項,另一種選擇是定義一個抽象,允許在對象圖中設置運行時值,它為調度程序提供該請求的信息。例如:
public interface IApplicationContext
{
AppType ApplicationType { get; set; }
}
您的控制器可以IApplicationContext注入它并設置AppType屬性:
public async Task<Response> ProcessRequest([FromBody] Request request)
{
var context = _someService.GetContext(request);
this.applicationContext.ApplicationType = ParseAppTypeFromContext(context);
this.dependency.DoSomethingElse();
}
或者,您可以添加一些中間件,AppType在調用控制器的 Action 方法之前設置。
您也可以讓代理實現IApplicationContext:
public class DependencyDispatcher : IDependency, IApplicationContext
{
...
public AppType ApplicationType { get; set; }
private IDependency Dependency => ApplicationType == AppType.A ? this.a : this.b;
// Implement IDependency methods to forward the call to Dependency
void IDependency.DoSomething() => this.Dependency.DoSomething();
}
- 1 回答
- 0 關注
- 274 瀏覽
添加回答
舉報