Я считаю, что вы говорите о регистрации всех типов в сборке, где некоторые типы в сборке могут нуждаться в регистрации с различным образом жизни. Таким образом, у вас есть 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();
}
}
}
проверит это, но если это сработает, это на самом деле будет очень простым решением! –
Добро пожаловать. Принципы поцелуя! – Crixo
я проверил, что это работает .. отлично! который знал все, что мне нужно было сделать, это переместить мое задание в несколько строк:] –