首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >寻找将温莎生活方式引入图书馆的方法

寻找将温莎生活方式引入图书馆的方法
EN

Stack Overflow用户
提问于 2019-05-01 20:14:30
回答 2查看 183关注 0票数 2

我们有一个web项目,它引用了一个库,这个库反过来在许多不同的系统之间共享。

库公开了一个"RegisterDependancies(IWindsorContainer容器)“函数,该函数在调用时将注册该特定库的所有依赖项。

因此,当web应用程序启动时,它自己注册,然后调用共享库,类似于下面的伪代码:

代码语言:javascript
复制
public void SetupWindsor(){

    IWindsorContainer container = new WindsorContainer();

    container.Register(Component.For<iFoo>().ImplementedBy<Foo>());

     SharedLibrary.RegisterDependancies(container);
}

共享库函数看起来有点像这样:

代码语言:javascript
复制
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项目使用PerWebRequest生活方式,但其他系统可能希望使用不同的生活方式(这个决定将取决于编写客户端应用程序的人--共享库将用于控制台和windows应用程序,因此perwebrequest不适合他们使用)

我们想改变RegisterDependancies方法,这样我们就可以通过生活方式了。

用PerWebRequest的生活方式可以做到这一点吗?我们中有几个人看了一眼,却看不出怎么做--尽管过去没有团结一致的问题,我们也做过类似的事情。

我们要么在寻找以上述方式解决问题的方法,要么有更好的方法来解决这一问题,这也将是有帮助的。

为了澄清,共享库将接口IBar定义为公共接口,而类Bar定义为内部接口,这样API就无法进行注册--除非我不知道温莎有什么魔力。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-11 14:15:57

共享库将接口IBar定义为公共接口,类条定义为内部接口,因此API无法进行注册。

让我们研究一下这个设计决策。虽然没有外部调用者可以创建Bar对象,但是他们可以创建IBar对象:

代码语言:javascript
复制
IWindsorContainer container = new WindsorContainer();
SharedLibrary.RegisterDependancies(container);
IBar bar = container.Resolve<IBar>();

保留Barinternal可能有各种原因,但是既然您已经可以像上面这样运行代码,为什么不让共享库公开一个工厂呢?

代码语言:javascript
复制
IBar bar = SharedLibrary.CreateBar();

这将更加简单,并将共享库与容器分离。通常,这是关于依赖注入和可重用库的最好建议:使用依赖注入模式,而不是容器。有关更多细节,请参阅我的文章迪友好型图书馆

如果您仍然希望在宿主项目(例如Wep API项目)中使用DI容器,则可以根据该静态工厂方法注册IBar

内部类

人们希望保留一些类internal是有正当理由的,但我经常看到代码库中的类是internal,没有明显的原因。我使用几十年C#代码的经验是,类是internal的情况没有什么好的理由,远远超过了有充分理由的情况。

Bar真的必须是内部的吗?为什么?

从OP中可以清楚地看到IBar是由Bar实现的。这可能是将问题简化为基本问题(做得很好,BTW),但我觉得Bar是实现IBar的唯一类。是这样吗?

如果是这样,Bar类必须公开由IBar定义的方法。因此,类的API已经公开,那么为什么要隐藏类呢?唯一隐藏的东西就是构造者..。

完美风暴

有时候,当我给出像上面这样的建议时,我会遇到一个不是这个问题的答案。问题是如何改变温莎城堡的生活方式(它,BTW,你可以的)。

另一方面,这个问题几乎是完美的(小小的)风暴,它说明了为什么可重用库不应该依赖于DI容器:

  • 库应该可以在多个上下文(web、控制台、桌面等)中使用。
  • 图书馆依靠温莎城堡
  • 接口是公共的,但实现类不是

这使事情复杂化-因此这里的问题在堆栈溢出。

我最好的建议是保持简单。消除对Castle的依赖将使库的开发和重用变得更容易,而不是更难。

如果将大多数库类公之于众,那么使用库就更容易了。

票数 1
EN

Stack Overflow用户

发布于 2019-05-02 07:02:47

可以使用LifeStyle.Is(LifestyleType)在组件注册上设置生活方式。

类似这样的东西将允许您传递生命周期。

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55942172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档