使用Castle Windsor时的装饰器模式,根据来电者

时间:2017-10-12 20:25:37

标签: c# dependency-injection castle-windsor

我想使用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需要注入UserViewModelFactory,其HomeV1ViewModelFactoryHomeV2Controller的依赖关系需要注入UserViewModelFactory,其依赖关系为{{1} }}

1 个答案:

答案 0 :(得分:1)

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

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