当需要根据调用者注入不同 class 时使用 Castle Windsor 的装饰器模式

Decorator pattern using Castle Windsor when different class need to be injected depending on caller

我想使用使用 Castle Windsor 的装饰器模式为我的 api 创建视图模型,但根据控制器将不同的 类 注入装饰器。我有两个版本的 api 端点。

一个用于 HomeV1Controller:

public class HomeV1Controller : ApiController {
    private readonly IHomeViewModelFactory _factory;

    public HomeV1Controller(IHomeViewModelFactory factory) {
        _factory = factory;
    }
} 

第二个:

public class HomeV2Controller : ApiController {
    private readonly IHomeViewModelFactory _factory;

    public HomeV2Controller(IHomeViewModelFactory factory) {
        _factory = factory;
    }
}

两个控制器都接受 IHomeViewModelFactory 它的定义是:

public interface IHomeViewModelFactory {
   HomeViewModel CreateViewModel(); 
}

现在我想为两个控制器注入公共视图模型工厂,并且该工厂需要调用下一个特定于控制器的视图模型工厂。所以我有一个工厂:

常见:

public class UserViewModelFactory : IHomeViewModelFactory {
    private readonly IHomeViewModelFactory _factory;

    public UserViewModelFactory(IHomeViewModelFactory factory) {
        _factory = factory;
    }

    public HomeViewModel CreateViewModel() {
        var vm = _factory.CreateViewModel();
        vm.User = new User();
        return vm;
    }
}

还有两个控制器专用:

public class HomeV1ViewModelFactory : IHomeViewModelFactory {
    public HomeViewModel CreateViewModel() {
        // logic only for V1 to create vm
        var vm = new HomeViewModel {
            Articles = new Articles()
        };
        return vm;
    }
}

public class HomeV2ViewModelFactory: IHomeViewModelFactory {
    public HomeViewModel CreateViewModel() {
        // logic only for V2 to create vm
        var vm = new HomeViewModel {
            Issues = new Issues()
        };
        return vm;
    }
}

现在 HomeV1Controller 需要注入具有 HomeV1ViewModelFactory 依赖关系的 UserViewModelFactory 并且 HomeV2Controller 需要注入具有 UserViewModelFactory 依赖关系的 UserViewModelFactory =22=].

我唯一能想到的就是服务覆盖:

        container.Register(Component.For<HomeV1Controller>()
            .DependsOn(Property.ForKey<IHomeViewModelFactory>().Is("UserViewModelFactory1")));
        container.Register(Component.For<HomeV2Controller>()
            .DependsOn(Property.ForKey<IHomeViewModelFactory>().Is("UserViewModelFactory2")));

        container.Register(Component.For<IHomeViewModelFactory>()
            .ImplementedBy<UserViewModelFactory>()
            .Named("UserViewModelFactory1")
            .DependsOn(Property.ForKey<IHomeViewModelFactory>().Is("HomeV1ViewModelFactory")));

        container.Register(Component.For<IHomeViewModelFactory>()
            .ImplementedBy<UserViewModelFactory>()
            .Named("UserViewModelFactory2")
            .DependsOn(Property.ForKey<IHomeViewModelFactory>().Is("HomeV2ViewModelFactory")));

        container.Register(Component.For<IHomeViewModelFactory>().ImplementedBy<HomeV1ViewModelFactory>().Named("HomeV1ViewModelFactory"));
        container.Register(Component.For<IHomeViewModelFactory>().ImplementedBy<HomeV2ViewModelFactory>().Named("HomeV2ViewModelFactory"));