亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

通過上下文解析依賴關系——深入解析樹

通過上下文解析依賴關系——深入解析樹

C#
RISEBY 2021-11-28 19:38:03
我們有兩個應用程序共享一些具有依賴項的公共類。這些依賴項對于兩者或特定于應用程序都是相同的?,F在為這兩個應用程序配置 IoC 很容易 - 使用 ImplementationA 作為一個應用程序的 IDependency,將 ImplementationB 作為另一個應用程序的 IDependency。但是 - 有第三個應用程序,有時在解析界面時需要使用應用程序 A 的依賴項,有時需要使用 B 的依賴項。換句話說,我需要這樣的東西:Resolve<ISomething>( when you come accross IDependecy (anywhere in the 'resolve tree') use ImplementationA)Resolve<ISomething>( when you come accross IDependecy (anywhere in the 'resolve tree') use ImplementationB)所以核心問題是:你如何將上下文傳遞給任何邏輯,從 Resolve 調用中選擇實現?具體示例:.NET Core MVC App - 從請求中解析枚舉值?,F在我需要調用一些 IManagerFactory,將此枚舉作為參數傳遞,并從應用程序 A 或 B 中獲取具有所有依賴項的管理器的實現。(再次,深入而不僅僅是管理器本身的依賴項)從請求中獲取上下文是時間消耗,所以我只想做一次。這已經在方法的開頭完成了。像這樣public async Task<Response> ProcessRequest([FromBody] Request request){ var context = _someService.GetContext(request); var appType = ParseAppTypeFromContext(context); ... var manager=  _managerFactory.Resolve(appType); manager.DoSomething(); manager.DoSomethingElse();}可能的解決方案:我可以注冊 ISomethingA,使用注冊委托并讓它通過 ResolvedParameter(Autofac 功能)解析正確的依賴項 - 然后只解析 ISomethingA。但是我必須為每個依賴于 IDependacy 的類以及依賴于該類的每個類等等都這樣做 - 繼續我的工作。使用工廠。但是您仍然必須以某種方式告訴它您想要哪種實現。所以我必須從上到下傳遞這些信息 - 這似乎有點......錯誤,因為這些是不應該知道有一些應用程序 A 或 B 的常見類。所以..我迷路了。我不確定這是否適用于 IoC 或更好的設計。請指教。(我真的不在乎我使用哪個 IoC 容器 - 只要它是好的和維護的)
查看完整描述

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();

}


查看完整回答
反對 回復 2021-11-28
  • 1 回答
  • 0 關注
  • 274 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號