2011-10-07 51 views
1

我是IoC和Castle Windsor的新手。Castle Windsor适用于多种混凝土类型的IoC容器示例

这个问题更多与IoC有关,但我只是选择Castle作为我选择的武器。

我马上跑进这似乎是不可能从一个配置文件或从一个单身构造容器的一个问题。

似乎为我工作的唯一方法是使用设计器功能,将每一次构建整个容器,然后让我指定类型,看看下面这个例子:

我有一个观点:

public interface IView 
{ 
} 

有此视图的2个具体实现:

public class ConcreteViewA : IView 
{ 
} 

public class ConcreteViewB : IView 
{ 
} 

我有在视图上操作的控制器:

public class Controller 
{ 
    public Controller(IView view) { } 
    public void Load() { } 
} 

我创建构建我的IoC容器和注册常见的类型,唯一的类型,我可以注册为我的控制器的功能,因为这是所有保持不变:

WindsorContainer BuildContainer() 
    { 
     var container = new WindsorContainer(); 
     container.Register(Component.For<Controller>().ImplementedBy<Controller>()); 
     return container; 
    } 

我有2个(根)入口点:

void RootMethod1() 
    { 
     var container = BuildContainer(); 
     container.Register(Component.For<IView>().ImplementedBy<ConcreteViewA>()); 
     var controller = container.Resolve<Controller>(); 
     controller.Load(); 
    } 

    void RootMethod2() 
    { 
     var container = BuildContainer(); 
     container.Register(Component.For<IView>().ImplementedBy<ConcreteViewB>()); 
     var controller = container.Resolve<Controller>(); 
     controller.Load(); 
    } 

正如你可以看到我每次都要重建容器,因为我需要告诉它使用什么IVIEW每个我在上下文的 如果集装箱。重建是昂贵的很多类型等),我怎么设计这个?

+0

这是一个MVC应用程序?如果是这样,那么一个IView的实例是做什么的? –

+0

我问,因为在一个ASP.Net应用程序中选择哪一个视图应该返回一个控制器上的Action是由框架处理的。 –

+0

不,这是winforms的自定义实现。页面加载事件将创建一个视图,该视图是当前实例的控制器/演示器(因此无法创建) – Andre

回答

5

从我的理解,你需要两个不同的Controller类实例(每个实例使用不同的IView类型构造)。实现此目的的最简单方法是注册两个具有不同名称和不同依赖关系的组件。

WindsorContainer BuildContainer() 
{ 
    var container = new WindsorContainer(); 

     container.Register(Component.For<Controller>().Named("ControllerWithViewA") 
                 .ImplementedBy<Controller>() 
                 .DependsOn(Property.ForKey(typeof(IView)) 
                 .Is(typeof(ConcreteViewA))); 
     container.Register(Component.For<Controller>().Named("ControllerWithViewB") 
                .ImplementedBy<Controller>() 
                .DependsOn(Property.ForKey(typeof(IView)) 
                .Is(typeof(ConcreteViewB))); 
    return container; 
} 

然后,您可以根据需要询问任何控制器。

void RootMethod1() 
{ 
    var container = BuildContainer(); 
    var controller = container.Resolve<Controller>("ControllerWithViewA"); 
    controller.Load(); 
} 

void RootMethod2() 
{ 
    var controller = container.Resolve<Controller>("ControllerWithViewB"); 
    controller.Load(); 
} 

一些事情用DI

  1. 建立你的容器只有一次(一次又一次的建筑是时间和资源的浪费)时,要牢记。

  2. 要非常确定注入哪些依赖关系,哪些不依赖关系。过度使用DI可能会导致臃肿的容器,这是一个维护噩梦。

  3. 来了解您的组件的生命周期(辛格尔顿,瞬态,每个线程等)。特别是对于Castle,默认的生活方式是单身,这可能会在多线程场景中产生不一致的行为。

1

你可以看看使用处理程序选择器。这将允许您根据您选择的任何代码动态选择要解析的视图。请参阅here