我想创建一个容器,它将允许解析ISomeService,但不能解析ISomeOtherService.即使我对ISomeService的注册依赖于ISomeOtherService.
那有意义吗?
public interface ISomeService {}
public interface ISomeOtherService {}
public class SomeService : ISomeService
{
public SomeService(ISomeOtherService someOtherService) {}
}
public class SomeOtherService : ISomeOtherService {}
我想要这个容器解析IsomeService的SomeService但是如果我试图解析ISomeOtherService或SomeOtherService它会失败.
这是糟糕的设计吗?
所以,一点上下文…我有ASP.Net MVC控制器,将由各种开发人员开发.那些控制器应该可以访问像ISomeService这样的应用程序服务,但不能访问它们的依赖项.我想避免代码审查所有这些服务,以确保开发人员不违反架构设计.他们应该能够获得对ISomeService的引用,但ISomeOtherService是一个DB存储库,他们不应该直接处理它,但ISomeService确实需要这个引用.
我不介意希望在解析过程中(这是一个ASP.NET MVC应用程序,我已经为Controller创建了一个扩展点)所以我可以看看正在解析的Controller,查看它的依赖关系并确保它们我是白名单,但我不知道如何轻松评估与温莎的依赖关系.或者,我是否必须通过查看构造函数参数来自己完成?
解决方法:
您可以使用SubDependencyResolver进行检查.请参阅以下代码:
public class SubDependencyResolver : ISubDependencyResolver
{
public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
// If not an ISomeotherComponent or SomeOtherComponent is resolved ignore.
if (dependency.TargetType != typeof (ISomeOtherComponent) && dependency.TargetType != typeof (SomeOtherComponent)) return false;
// check if we are resolving for SomeComponent
if (model.Implementation == typeof (SomeComponent)) return false;
// We are resolving for a different component then SomeComponent.
Debug.Assert(false);
return false;
}
public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model,
DependencyModel dependency)
{
// We will never actually resolve the component, but always use the standard SubDependencyResolver, as Can resolve always returns false;
return null;
}
}
class Program
{
static void Main(string[] args)
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new SubDependencyResolver());
container.Register(
Component.For<ISomeOtherComponent>().ImplementedBy<SomeOtherComponent>(),
Component.For<ISomeComponent>().ImplementedBy<SomeComponent>(),
Component.For<Legal>()
// Component.For<Illegal>() uncommenting this line will assert.
);
}
}
public interface ISomeComponent
{
}
public interface ISomeOtherComponent
{
}
public class SomeComponent : ISomeComponent
{
public SomeComponent(ISomeOtherComponent someOtherComponent)
{
}
}
public class SomeOtherComponent : ISomeOtherComponent
{
}
public class Legal
{
public Legal(ISomeComponent component)
{
}
}
public class Illegal
{
public Illegal(ISomeOtherComponent component)
{
}
}