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 关注
- 244 浏览
添加回答
举报