gpt4 book ai didi

c# - 适合 Unity 的抽象工厂

转载 作者:行者123 更新时间:2023-11-30 16:55:46 30 4
gpt4 key购买 nike

我们正在构建一个与其他系统有多个集成接触点的应用程序。我们有效地使用 Unity 来满足我们所有的依赖注入(inject)需求。整个业务层是用接口(interface)驱动的方法构建的,实际实现在应用程序引导期间注入(inject)到外部组合根。

我们希望以优雅的方式处理集成层。业务类和存储库依赖于 IIntegrationController<A, B>接口(interface)。几个IIntegrationController<A, B>实现一起表示在后台与一个目标系统集成——形成一个集成层。目前,我们在一开始就连接了构图根中的所有内容,一个镜头。该接口(interface)的消费者也注册了一个适当的InjectionConstrutor。和 ResolvedParameter在前面。大多数类型都使用 PerResolveLifetime 操作和使用 IIntegrationController 的业务类也分别针对每个请求上下文进行解析。

引用下面的代码。

        // IIntegrationController Family 1
// Currently the default registration for IIntegrationController types injected into the business classes
container.RegisterType<IIntegrationController<A, B>, Family1-IntegrationController<A, B>>();
container.RegisterType<IIntegrationController<C, D>, Family1-IntegrationController<C, D>>();

// IIntegrationController Family 2 (currently not registered)
// We want to be able to register this, or manage this set of mapping registrations separately from Family 1,
// and be able to hook these up dynamically instead of Family-1 on a per-resolve basis
container.RegisterType<IIntegrationController<A, B>, Family2-IntegrationController<A, B>>();
container.RegisterType<IIntegrationController<C, D>, Family2-IntegrationController<C, D>>();

// Repository/Business Class that consume IIntegrationControllers.
// There is a whole family of IIntegrationController classes being hooked in,
// and there are multiple implementations for the family (as shown above). A typical AbstractFactory scenario.
container.RegisterType(typeof(Repository<Z>), new PerResolveLifetimeManager(),
new InjectionConstructor(
new ResolvedParameter<IIntegrationController<A, B>>(),
new ResolvedParameter<IIntegrationController<C, D>>())
);

问题陈述:

我们希望能够切换整个 IIntegrationController<A, B> 系列在运行时。当业务类被解析时,我们希望它被注入(inject)正确版本的IIntegrationController<A, B>。 ,基于上下文中可用的请求参数。

  • 基于“命名”注册的解决方案不可扩展,原因有二(必须切换整个集成类系列,并且代码中需要笨重的名称注册和条件解析,因此难以维护) .
  • 即使存在解决方案的链/层次结构,即 IIntegrationController 的直接消费者,该解决方案也应该有效。也是通过 Unity 解决的,因为它是动态注入(inject)到另一个类中的。
  • 我们尝试了 DependencyOverrideResolveOverride在决议期间上课,但这需要整套 Family-2 IIntegrationController要覆盖的分辨率,而不是仅仅能够切换整个层。
  • 我们知道,不是将 IIntegrationController 直接注入(inject)业务类,而是可能必须注入(inject) AbstractFactory,但我们无法使其正常工作,并且不确定注册和解析将在何处进行。如果业务类与 AbstractFactory Hook ,首先我必须为每个解析 Hook 正确的工厂,
  • 这是否需要覆盖 InjectionFactoryThis link提出了一种方法,但我们无法使其顺利运行。

最佳答案

您的设计的优点在于您已经有了正确的抽象。您使用通用抽象,因此可以通过在您已经 SOLID 的设计之上应用正确的模式来简单地解决问题。

换句话说,使用代理:

// This class should be considered part of your composition root.
internal class IntegrationControllerDispatcher<TRequest, TResult>
: IIntegrationController<TRequest, TResult>
{
private readonly IUserContext userContext;
private readonly Family1_IntegrationController<A, B> family1Controller;
private readonly Family2_IntegrationController<A, B> family2Controller;

public IntegrationControllerDispatcher(
IUserContext userContext,
Family1_IntegrationController<A, B> family1Controller,
Family2_IntegrationController<A, B> family2Controller) {
this.userContext = userContext;
this.family1Controller = family1Controller;
this.family2Controller = family2Controller;
}

public TResult Handle(TRequest request) {
return this.GetController().Handle(request);
}

private IIntegrationController<TRequest, TResult> GetController() {
return this.userContext.IsInFamily("family1"))
? this.family1Controller
: this.family2Controller;
}
}

有了这个类,你的整个配置可以简化为:

container.RegisterType<IUserContext, AspNetUserContext>();

container.RegisterType(
typeof(IIntegrationController<,>),
typeof(IntegrationControllerDispatcher<,>));

container.RegisterType(typeof(Repository<>), typeof(Repository<>));

注意以下几点:

  • 注意使用注册进行开放式通用映射。您不必一一注册所有封闭版本。您只需一行代码即可完成。
  • 另请注意,不同系列的类型并不相同挂号的。 Unity 可以自动解决它们,因为我们的IntegrationControllerDispatcher 直接依赖于它们。这类是基础设施逻辑的一部分,应该放在里面你的组合根。
  • 请注意,使用特定系列实现的决定并不是在构建对象图期间做出的;它是在运行时生成的,因为决定这个的值是运行时值。试图在构建对象图时确定这一点,只会使事情复杂化,并使验证对象图变得更加困难。
  • 此外,此运行时值在函数调用之后被抽象化并置于抽象之后(在本例中为 IUserContext.IsInFamily,但这当然只是一个示例)。

关于c# - 适合 Unity 的抽象工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29025485/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com