我们有一个Web api项目,该项目引用了一个库,该库又在许多不同的系统之间共享。
该库公开了一个“ RegisterDependancies(IWindsorContainer container)”函数,该函数在调用时将注册该特定库的所有依赖项。
因此,当Web api应用程序启动时,它将进行自己的注册,然后调用共享库,类似于以下伪代码:
public void SetupWindsor(){
IWindsorContainer container = new WindsorContainer();
container.Register(Component.For<iFoo>().ImplementedBy<Foo>());
SharedLibrary.RegisterDependancies(container);
}
共享库函数看起来像这样:
public void RegisterDependancies(IWindsorContainer container)
{
container.Register(Component.For<iBar>().ImplementedBy<Bar>());
//In this instance Bar is internal so could not be registered by the api project.
}
我们现在希望Web api项目使用PerWebRequest生活方式,但其他系统可能希望使用不同的生活方式(此决定将取决于编写客户端应用程序的人-共享库将用于控制台和Windows应用程序-因此perwebrequest不适合他们使用)
我们想更改RegisterDependancies方法,以便我们能够过上这种生活方式。
PerWebRequest生活方式是否可以做到这一点?尽管过去做过类似的工作,但没有团结的问题,但我们中的一些人却一眼也不知道该怎么做。
我们正在寻找一种以上述方式解决问题的方法,或者是否有更好的方法来解决该问题也将有所帮助。
编辑以明确说明,共享库将接口IBar定义为公共接口,而将类Bar定义为内部接口,因此API无法进行注册-除非我不知道温莎有什么魔力。
答案 0 :(得分:1)
您可以使用 LifeStyle.Is(LifestyleType)
这样的事情可以让您传递生命周期。
public void RegisterDependencies(IWindsorContainer container, Castle.Core.LifestyleType lifestyleType)
{
container.Register(Component.For<IBar>().ImplementedBy<Bar>().LifeStyle.Is(lifestyleType));
}
或者,按照惯例在程序集中进行注册,这将允许从API项目中控制生活方式,而无需公共实现 https://github.com/castleproject/Windsor/blob/master/docs/registering-components-by-conventions.md
答案 1 :(得分:0)
共享库将接口IBar定义为公共接口,但将Bar类定义为内部接口,因此API无法注册
让我们检查一下该设计决策。尽管没有外部调用者可以创建Bar
对象,但他们可以创建IBar
对象:
IWindsorContainer container = new WindsorContainer();
SharedLibrary.RegisterDependancies(container);
IBar bar = container.Resolve<IBar>();
保留Bar
类internal
可能有多种原因,但是由于您已经可以运行上述代码,所以为什么不简单地让共享库公开工厂呢?
IBar bar = SharedLibrary.CreateBar();
那会简单得多,并将共享库与容器解耦。通常,这是我可以提供的有关依赖关系注入和可重用库的最佳建议:使用依赖关系注入模式,而不是容器。有关更多详细信息,请参见我的文章DI-Friendly Library。
如果您仍想在宿主项目(例如Wep API项目)中使用DI容器,则可以针对该静态工厂方法注册IBar
。
出于某些合理的原因,我们希望保留一些类internal
,但是我经常看到没有明显原因的代码库,其中的类是internal
。我使用数十年C#代码的经验是,无缘无故地使用internal
类的情况远胜于有充分理由的情况。
Bar
是否真的必须是内部的?为什么?
在OP中,很明显IBar
由Bar
实现。这个可以是将问题简化为基本要素的人为因素(这样做很好,顺便说一句),但我的印象是Bar
是唯一的 类,实现IBar
。是这样吗?
如果是,则Bar
类必须公开IBar
定义的方法。因此,该类的API已经公开,那么为什么要隐藏该类呢?那么,唯一隐藏的是构造函数...
有时候,当我提供上述建议时,我遇到的答复不是问题所在。问题在于如何改变温莎城堡的生活方式(顺便说一下,you can)。
另一方面,这个问题几乎是一场完美的风暴,它说明了为什么可重用库不应该依赖DI容器:
这使事情变得复杂-因此出现了堆栈溢出的问题。
我最好的建议是保持简单。消除对Castle Windsor的依赖将使库的开发和重用更加容易,而不是更加困难。
如果您将大多数库类公开,则使用该库将更加容易。