C# 当需要根据调用方注入不同的类时,使用Castle Windsor的装饰器模式
我想使用Castle Windsor的decorator模式为我的api创建视图模型,但根据控制器的不同,将不同的类注入到decorator中。我有两个版本的api端点 一个用于HomeV1Controller:C# 当需要根据调用方注入不同的类时,使用Castle Windsor的装饰器模式,c#,dependency-injection,castle-windsor,C#,Dependency Injection,Castle Windsor,我想使用Castle Windsor的decorator模式为我的api创建视图模型,但根据控制器的不同,将不同的类注入到decorator中。我有两个版本的api端点 一个用于HomeV1Controller: public class HomeV1Controller : ApiController { private readonly IHomeViewModelFactory _factory; public HomeV1Controller(IHomeViewMode
public class HomeV1Controller : ApiController {
private readonly IHomeViewModelFactory _factory;
public HomeV1Controller(IHomeViewModelFactory factory) {
_factory = factory;
}
}
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;
}
}
第二:
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 HomeV1Controller : ApiController {
private readonly IHomeViewModelFactory _factory;
public HomeV1Controller(IHomeViewModelFactory factory) {
_factory = factory;
}
}
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
需要注入依赖于HomeV2ViewModelFactory的UserViewModelFactory
我唯一能想到的是服务覆盖:
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"));
container.Register(Component.For())
.DependsOn(Property.ForKey().Is(“UserViewModelFactory1”);
container.Register(Component.For())
.DependsOn(Property.ForKey().Is(“UserViewModelFactory2”));
container.Register(Component.For())
.由()实施
.命名(“UserViewModelFactory1”)
.DependsOn(Property.ForKey().Is(“HomeV1ViewModelFactory”);
container.Register(Component.For())
.由()实施
.命名(“UserViewModelFactory2”)
.DependsOn(Property.ForKey().Is(“HomeV2ViewModelFactory”);
container.Register(Component.For().ImplementedBy().Named(“HomeV1ViewModelFactory”);
container.Register(Component.For().ImplementedBy().Named(“HomeV2ViewModelFactory”);
通常情况下,我们不会在ViewModels中放置任何业务逻辑,因此没有理由模拟它们或返回DI容器来创建它们。使用new
关键字就足够了。有关更多详细信息,请参阅。@NightOwl888我没有在视图中加入任何逻辑来查看模型本身。但是逻辑解释了vm是如何创建的,这很好。我的观点是,没有理由使用工厂或DI容器来创建视图模型。在这个场景中,您不需要抽象。您拥有的代码看起来不错(除了不必要的IHomeViewModelFactory
constructor参数)。那么除了HomeV1ViewModelFactory和HomeV2ViewModelFactory之外,还有什么样的IHomeViewModelFactory依赖项呢?@JanMuncinsky无,装饰程序结束了。我将更新示例。