Ускоритель Caliburn Micro и Windsor Castle {Нет компонента для поддержки сервиса}

#wpf #dependency-injection #castle-windsor #caliburn.micro #bootstrapper

#wpf #внедрение зависимостей #castle-Виндзор #caliburn.micro #загрузчик

Вопрос:

Привет, я пытаюсь использовать Windosor Castle с Caliburn Micro. До сих пор я использую только MEF.

Я нашел этот ускоритель Castle:https://gist.github.com/1127914

Я добавил эти вызовы в свой проект и изменил файл App.xaml:

 <Application x:Class="Chroma_Configer.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Bootstraper="clr-namespace:Chroma_Configer.Bootstraper">
    <Application.Resources>
        <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary>
                    <Bootstraper:CastleBootstrapper x:Key="bootstrapper" />

                <Style x:Key="MainView_FontBaseStyle" TargetType="{x:Type Control}">
                    <Setter Property="FontFamily" Value="Arial"/>
                </Style>
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>
    </Application.Resources>
</Application>
  

Я создаю ShellView (WPF) и ShellViewModel:

 public interface IShellViewModel
{

}


public class ShellViewModel : Conductor<IScreen>.Collection.OneActive,
    IShellViewModel
{

}
  

При запуске я получаю эту ошибку:

 {"No component for supporting the service Chroma_Configer.ViewModels.IShellViewModel was found"}
  

Я новичок в Виндзорском замке, я знаю, что он работает примерно так:

         var container = new WindsorContainer();
        container.AddComponent("JsonUtil", typeof(IShellViewModel), typeof(ShellViewModel));

        var shell = container.Resolve<IShellViewModel>();
  

В MEF я использую пользовательские атрибуты [Экспорт] и [Импорт]. Может ли кто-нибудь помочь мне с этой проблемой?

Другой вопрос в том, что у меня есть некоторый класс инструментов:

 public interface ITooll{}

public class Tool:ITool{}
  

и я хотел бы импортировать это в класс ShellViewModel.

Как я могу это сделать с помощью с помощью CastleBoostraper?

Ответ №1:

Вам необходимо зарегистрировать свои модели просмотра и представления в контейнере. Более старая версия Windsor работала на основе атрибутов, но в последней версии вы можете сделать это с помощью fluent API или даже bulk register на основе некоторого соглашения:

 public class Bootstrapper : Bootstrapper<IShellViewModel>
{
    protected override IServiceLocator CreateContainer()
    {
        _container = new WindsorContainer();
        var adapter = new WindsorAdapter(_container);
        _container.Register(Component.For<ITool>().ImplementedBy<Tool>().LifeStyle.Transient);

        return adapter;
    }
}
  

Вы также можете создать установщики, которые будут регистрировать типы в контейнере, чтобы в вашем коде загрузчика не было большого количества регистрационного кода:

 public class ShellRegistration : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Component.For<ITool>().ImplementedBy<Tool>().LifeStyle.Transient);
        //Register other types
    }
}
  

И вызовите его в загрузчике:

 public class Bootstrapper : Bootstrapper<IShellViewModel>
{
    protected override IServiceLocator CreateContainer()
    {
        _container = new WindsorContainer();
        var adapter = new WindsorAdapter(_container);
        _container.Install(FromAssembly.This());

        return adapter;
    }
}
  

Проверьте пример приложения Silverlight, которое я создал, чтобы узнать, как работать с Castle Windsor.

Вы можете получить экземпляры ваших зависимостей, используя внедрение конструктора или свойство, встроенное в это:

 public class ShellViewModel
{
    public ShellViewModel(IMyDependency dependency)
    {
       //you'll get an instance of the class implementing IMyDependency
       //Logger property will be injected after construction
    }

    public ILog Logger
    {
        get; set;
    }
}