Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当需要根据调用方注入不同的类时,使用Castle Windsor的装饰器模式_C#_Dependency Injection_Castle Windsor - Fatal编程技术网

C# 当需要根据调用方注入不同的类时,使用Castle Windsor的装饰器模式

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

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

一个用于HomeV1Controller:

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无,装饰程序结束了。我将更新示例。