2013-11-26 3 views
0

Я провел некоторое время, оглядываясь по сторонам, и, похоже, не существует очевидного решения этого сценария.Замок Виндзор Конфигурация образа жизни

зарегистрировать все типы из сборки (это около 80 типов, интерфейсы в отдельной сборке)

public static void RegisterAllFromAssemblies(string a) 
    { 
     IoC.Container.Register(
      AllTypes.FromAssemblyNamed(a) 
       .Pick() 
       .WithService.FirstInterface() 
       .Configure(o => o.LifeStyle.PerWebRequest) 
      ); 
    } 

теперь говорят, что если я хочу использовать другой LifeStyle для одного из этих объектов, я не могу переопределить, так как я получу Компонент, уже зарегистрированный для данного ключа Ошибка.

Я рассмотрел различные способы изменения образа жизни после этой регистрации, но до сих пор не смог ничего сделать.

Какое должно быть идеальное решение здесь? я бы предпочел не отказываться от функциональности AllTypes.

я полагаю, я мог бы указать .гд фильтра, когда регистрирующие все и пропустить несколько объектов, которые необходимо зарегистрировать вручную, но это не очень enterprisey решение ..

ответ

1

Это вариант для регистрации вручную исключения в первую очередь? Если это так, компоненты, зарегистрированные вручную, не будут перерегистрированы «AllTypes» (я предлагаю вам вместо этого использовать классы). Если вы зарегистрируете вручную компонент после регистрации «группы», будет выбрано исключение, но не наоборот.

Например

//YourImplementation lives in assembly 'a' 
IoC.Container.Register(
    Component.For<YourInterface>().ImplementedBy<YourImplementation>().LifestyleSingleton() 
    ); 

IoC.Container.Register(
    Classes.FromAssemblyNamed(a) 
     .Pick() 
     .WithService.FirstInterface() 
     .Configure(o => o.LifeStyle.PerWebRequest) 
    ); 
+0

проверит это, но если это сработает, это на самом деле будет очень простым решением! –

+0

Добро пожаловать. Принципы поцелуя! – Crixo

+0

я проверил, что это работает .. отлично! который знал все, что мне нужно было сделать, это переместить мое задание в несколько строк:] –

3

Я считаю, что вы говорите о регистрации всех типов в сборке, где некоторые типы в сборке могут нуждаться в регистрации с различным образом жизни. Таким образом, у вас есть IRepository, который должен быть PerWebRequest и ITypeMapper, который может быть singleton.

Я уточняю, потому что вы также можете иметь в виду, что вы хотите, чтобы IRepository был PerWebRequest в одном месте вашего кода и одноэлементным в другом месте. Без создания сумасшедшего образа жизни вы можете создать свой компонент и зарегистрировать его для образа жизни по умолчанию. Если вам нужен другой образ жизни, иногда вы можете создать новый компонент и наследовать от существующего только для использования в регистрации (пример кода показывает это, если это запутывает).

Я написал образец, чтобы он работал для любого сценария, и я дал несколько разных подходов, которые фокусируются вокруг возможностей фильтрации при одновременном настройке нескольких элементов.

Для этого я вызываю конфигурацию для конкретного компонента по типу. Это не так, как вы выразились, как «enerprisey», но цель понятна, если у вас есть только несколько исключений из правила. Вы заметите, что можете объединить настройки. Если это не требуется, потому что вторая конфигурация подберет компонент для первой настройки, поскольку мое единственное условие - это службы, основанные на IService. Это предполагает, что замок обрабатывает настройки в порядке. Я считаю, что предположение звучит, но на некоторое время не смотрел на источник.

container.Register(
    Classes.FromThisAssembly() 
     .BasedOn<IService>() 
     .ConfigureFor<MyComponentAsSingleton>(component => component.LifestyleSingleton()) 
     .Configure(component => component.LifestylePerWebRequest()).Unless(type => container.Kernel.GetAssignableHandlers(type).Count() > 0)); 

Это один использует атрибуты более обобщенно отклоняться от нормального образа жизни «PerWebRequest

container2.Register(
    Classes.FromThisAssembly() 
     .BasedOn<IService>() 
     .ConfigureIf(
      //condition to check - do we have our custom Attribute? 
      registration => registration.Implementation.GetCustomAttributes(false).Any(attr => typeof(ShouldBeSingleton).IsAssignableFrom(attr.GetType())), 
      //if true register as singleton 
      component => component.LifestyleSingleton(), 
      //else register as per web request 
      component => component.LifestylePerWebRequest() 
      )); 

Теперь, когда я дал вам несколько образцов, которые решают проблему немедленного (как я понимаю) пусть я даю вам мой совет бесплатно!

Сначала мне не очень нравится WithService.FirstInterface(). Поскольку intelisense утверждает, что он не детерминирован, когда вы реализуете несколько интерфейсов. Любой разработчик может войти и сделать безвредное изменение интерфейса к классу и en разбить систему. Если вы можете уйти с WithService.DefaultInterfaces(), у вас будет труднее испортить решение. Интерфейсы по умолчанию просто говорят, что замок, регистрируя компонент Foo, использует сервис IFoo, если он реализует интерфейс с именем IFoo.

Во-вторых, я считаю, что если вы разделите свою регистрационную логику на единые единицы, вы, вероятно, не столкнулись бы с этой проблемой. Ключ должен иметь много файлов установщика, которые реализуют IWindsorInstaller. Внутри этих установщиков вы регистрируетесь (используя классы или типы, чтобы сохранить их все еще), которые имеют смысл для конкретного установщика. Шансы на то, что у вас несколько проблем с обращением к жизни в одном и том же инсталляторе, довольно низки (и если вы найдете это, вам, вероятно, потребуется больше инсталляторов)

Если вы следовали этому подходу, вы могли бы закончить с помощью RepositoryInstaller, ViewInstaller, ControllerInstaller и т. Д. . More on installers can be found on the castle documentation site

Что бы вы могли сделать, если хотите, тогда у вас есть общий ускоритель для всех ваших систем, который смотрит в каталог приложения и устанавливает все инсталляторы, которые находятся в каталоге. Если бы это было не то, о чем вы просили, я перестану разбираться, но если вы заинтересованы, вы можете пинговать меня, и я могу показать вам больше о том, о чем я говорю.

Полный пример кода в качестве консольного приложения:

using Castle.MicroKernel.Registration; 
using Castle.Windsor; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace MultipleLifecyles 
{ 
    [AttributeUsage(AttributeTargets.Class)] 
    public class ShouldBeSingleton : Attribute 
    { 
    } 

    public interface IService 
    { 
     void DoSomething(); 
    } 

    public class MyComponent : IService 
    { 
     public void DoSomething() 
     { 
      throw new NotImplementedException(); 
     } 
    } 

    [ShouldBeSingleton] 
    public class MyComponentAsSingleton : MyComponent 
    { 

    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 

      //option 1 
      IWindsorContainer container = new WindsorContainer(); 

      container.Register(
       Classes.FromThisAssembly() 
        .BasedOn<IService>() 
        .ConfigureFor<MyComponentAsSingleton>(component => component.LifestyleSingleton()) 
        .Configure(component => component.LifestylePerWebRequest()).Unless(type => container.Kernel.GetAssignableHandlers(type).Count() > 0)); 

      IWindsorContainer container2 = new WindsorContainer(); 

      container2.Register(
       Classes.FromThisAssembly() 
        .BasedOn<IService>() 
        .ConfigureIf(
         //condition to check - do we have our custom Attribute? 
         registration => registration.Implementation.GetCustomAttributes(false).Any(attr => typeof(ShouldBeSingleton).IsAssignableFrom(attr.GetType())), 
         //if true register as singleton 
         component => component.LifestyleSingleton(), 
         //else register as per web request 
         component => component.LifestylePerWebRequest() 
         )); 


      Console.ReadLine(); 
     } 
    } 
} 
+0

ценят хорошую рецензию! +1, но другой ответ на самом деле именно то, что я искал .. принимая до тех пор, пока я не увижу проблемы с ним –

Смежные вопросы