I'm trying to overwrite a component registration (done via xml) with another one (in another xml, loaded via code using container.Install(Configuration.FromXmlFile("..."))
that has the same component id, but i receive an error saying:
我正在尝试用另一个(在另一个xml中,通过使用container.Install(Configuration.FromXmlFile(“...”)的代码加载)来覆盖组件注册(通过xml完成),它具有相同的组件ID,但是我收到错误说:
"Component COMP_ID could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name."
“组件COMP_ID无法注册。已经有一个具有该名称的组件。您是否要修改现有组件?如果没有,请确保指定唯一名称。”
The thing is, i in fact actually would like to modify the existing component, to be able to define basic wiring in a basic castle.xml file and then overwrite it, in another custom.xml file, loaded after the basic one.
事实上,我实际上想要修改现有组件,以便能够在基本的castle.xml文件中定义基本连线,然后在另一个custom.xml文件中覆盖它,在基本的文件之后加载。
I'm trying to use the same component id because a tought it would have rewritten the previous registration.
我正在尝试使用相同的组件ID,因为它应该重写之前的注册。
The reality is that i would like to change wich implementation is used to respond to a service, the component id is just a try that i've done. Since Castle has a policy of first-registration-wins, it would be enough for example to switch to a last-registration-wins, for example.
实际情况是,我想改变用于响应服务的实现,组件ID只是我已经完成的尝试。由于Castle具有首次注册获胜的策略,例如,切换到最后注册获胜就足够了。
Concrete example
Let's use the example of an ILogger
interface.
我们来看一个ILogger接口的例子。
The basic castle.xml (loaded always) would be like this:
基本的castle.xml(总是加载)将是这样的:
<component id="logger" service="ILogger" type="NullLogger" ></component>
The castle.dev.xml file (loaded only in the dev ambient, after the default one) would look like this:
castle.dev.xml文件(仅在dev环境中加载,默认加载后)将如下所示:
<component id="logger" service="ILogger" type="AspNetTraceLogger" ></component>
The castle.prod.xml file (loaded only in production ambient, after the default one, instead of the dev one) would look like this:
castle.prod.xml文件(仅在生产环境中加载,在默认加载后,而不是开发者)将如下所示:
<component id="logger" service="ILogger" type="SqlServerLogger" ></component>
Now: for each of these configurations, I would like to say "respond to ILogger requests with this impl", so I need to have only one of them to respond to requests for ILogger at each time.
现在:对于这些配置中的每一个,我想说“用这个impl响应ILogger请求”,所以我只需要其中一个响应每次ILogger的请求。
Anyone have any idea?
有人有什么想法吗?
update
I'll add: as of now i'm using a, shall we say, "reverse overwriting" technique, where i load the overwriting files "first", before the corresponding "default" ones. In this way, since the policy is first-wins, i can declare them as overwrites, even though internally they are declared before. The problem with this approach is when i have an interface that i know will be implemented more than once (say, IWhateverListener): in this case i cannot remove the other ones already registered, and cannot use the first-wins solution because later on i'll use a ResolveAll() and the "default ones" will be used too.
我将补充:截至目前我正在使用a,我们应该说,“反向覆盖”技术,我在相应的“默认”之前加载覆盖文件“first”。通过这种方式,由于策略是第一次获胜,我可以将它们声明为覆盖,即使它们之前已在内部声明。这种方法的问题是当我有一个我知道将不止一次实现的接口(比如,IWhateverListener):在这种情况下我不能删除已注册的其他接口,并且不能使用先赢的解决方案因为稍后我将使用ResolveAll(),并且也将使用“默认值”。
1 个解决方案
#1
1
Don't try to register several components with the same ID, or try to hack around it.
不要尝试使用相同的ID注册多个组件,或尝试破解它。
If you must use XML, take a look at defines and ifs.
如果必须使用XML,请查看定义和ifs。
Otherwise just use different installers, one for each environment, and at application startup register the one you want
否则只需使用不同的安装程序,每个环境一个,并在应用程序启动时注册您想要的安装程序
#1
1
Don't try to register several components with the same ID, or try to hack around it.
不要尝试使用相同的ID注册多个组件,或尝试破解它。
If you must use XML, take a look at defines and ifs.
如果必须使用XML,请查看定义和ifs。
Otherwise just use different installers, one for each environment, and at application startup register the one you want
否则只需使用不同的安装程序,每个环境一个,并在应用程序启动时注册您想要的安装程序