캐슬 윈저의 Fluent API를 사용하여 명명 규칙을 기반으로 서비스에 대한 구현을 자동 등록합니다 (어떤 것이 Something에 의해 구현 됨). 한 가지 지원하고자하는 것은 자동 등록이 별도의 dll에있는 종속성을 선택하고 자동 등록하는 것입니다.캐슬 윈저 및 자동 등록
So : IFoo는 Foo (둘 다 Foo.dll)에서 구현되며 Foo는 Bar.dll에있는 IBar에 종속됩니다.
다음 코드는 실제로 자동 등록을 수행하도록 작성되었습니다. 그것은 효과가있는 것 같지만, 내가 너무 많은 일을했는지 궁금합니다. 동일한 것을 성취하는 더 간단한 방법이 있습니까?
private static void EnsureRegistered(Type t, IWindsorContainer container)
{
if (!container.Kernel.HasComponent(t) && (!(t.Assembly.FullName.StartsWith("System") || t.Assembly.FullName.StartsWith("mscorlib"))))
{
bool registeredAtLeastOneComponent = false;
container.Register(AllTypes.Pick().
FromAssembly(t.Assembly).If(delegate(Type t2)
{
//auto-registers all types that implement an interface where
//the name of the interface is the same as the class, minus the 'I'
//ex: EchoService is auto-registered as handler of IEchoService
Type[] interfaces = t2.GetInterfaces();
bool shouldRegister = false;
foreach(Type interfaceType in interfaces)
{
shouldRegister = t2.Name.Equals(interfaceType.Name.Substring(1))
&& (!container.Kernel.HasComponent(interfaceType));
registeredAtLeastOneComponent = registeredAtLeastOneComponent || shouldRegister;
if (shouldRegister)
break;
}
return shouldRegister;
}).WithService.Select(delegate(Type type, Type baseType)
{
Type serviceType = null;
Type[] interfaces = type.GetInterfaces();
foreach(Type interfaceType in interfaces)
{
if (!type.Name.Equals(interfaceType.Name.Substring(1))) continue;
serviceType = interfaceType;
break;
}
return new Type[] {serviceType};
}));
if (!registeredAtLeastOneComponent)
return;
//for each of the items in the graph, if they have see if they have dependencies
//in other assemblies that aren't registered, register those dependencies as well
foreach(GraphNode registered in container.Kernel.GraphNodes)
{
if (!(registered is Castle.Core.ComponentModel))
continue;
Castle.Core.ComponentModel registeredComponent = registered as Castle.Core.ComponentModel;
foreach(ConstructorCandidate constructor in registeredComponent.Constructors)
{
foreach(DependencyModel dep in constructor.Dependencies)
{
EnsureRegistered(dep.TargetType, container);
}
}
}
}
}
답변 해 주셔서 감사합니다. 내가하고있는 일은 일부 레거시 앱에 컨테이너를 도입하고 컨테이너를 사용할 때 무 마찰 ('IBar은 Bar Convention으로 구현 됨'을 준수하는 한)으로 진행하는 것입니다. 그리고 합의 : 복잡한 시나리오. 80 %의 경우를 여기에서 칠하려고 노력한다. –
그 경우 코드가 그 목적을 잘 수행해야합니다! –
감사합니다. 내가 말했듯이, 나는 주로 내가 더 간단한 길을 잃어 버렸는지를보기 위해 찾고 있었다. 그리고 여러분이 지적했듯이, 물건을 더 단순하게 만드는 한 가지 방법은 컨테이너 주변의 물건을 단순화하는 것입니다 :-) –