C# 如何使用castle windsor将运行时参数传递给以前注册的工厂方法?
我有一个使用Castle Windsor的报告MVC应用程序 在应用程序启动时(在global.asax中),所有类型都会被注册,然后对应用程序的每个后续请求都会解析相关的报告类型,windsor会自动处理依赖项 我需要根据请求中传入的参数,将一个依赖类型切换为另一个依赖类型 我怎样才能做到这一点 我已向windsor注册了一个factory方法来处理可切换类型的解析,但由于这是在应用程序启动时注册的,当参数仅在以后的请求中可用时,我如何将参数传递给factory方法C# 如何使用castle windsor将运行时参数传递给以前注册的工厂方法?,c#,.net,castle-windsor,castle,C#,.net,Castle Windsor,Castle,我有一个使用Castle Windsor的报告MVC应用程序 在应用程序启动时(在global.asax中),所有类型都会被注册,然后对应用程序的每个后续请求都会解析相关的报告类型,windsor会自动处理依赖项 我需要根据请求中传入的参数,将一个依赖类型切换为另一个依赖类型 我怎样才能做到这一点 我已向windsor注册了一个factory方法来处理可切换类型的解析,但由于这是在应用程序启动时注册的,当参数仅在以后的请求中可用时,我如何将参数传递给factory方法 如果我尝试为每个请求注册工
如果我尝试为每个请求注册工厂,它会在第一个请求上工作,但随后会在所有请求上抱怨工厂已注册。在每次请求后注销工厂听起来不是正确的做法。当您需要在运行时解析类型时,通常的解决方案是注入一个工厂,该工厂可以在适当的时间做出决定:
public class ReportFactory: IReportFactory {
IReport CreateReport(bool useDefault) {
if (useDefault) {
return new DefaultReport();
} else {
return new UnusualReport();
}
}
}
以前需要
IReport
的类应该要求使用IReportFactory
。您肯定不想根据每个请求修改容器。这是灾难的秘诀
你有两个选择。第一种方法是在工厂方法中使用HttpContext.Current
IWhatever CreateWhatever() {
if (HttpContext.Current.Request["parameter"] == "value-for-other-whatever")
return new FirstWhatever();
return DefaultWhatever();
}
另一个(更好的)选项是注入一个解析正确实现的工厂类型,而不是让容器为您执行
public class WhateverFactory : IWhateverFactory {
public IWhatever GetWhatever(string parameter) {
if(parameter == "value for other whatever")
return new OtherWhatever();
return new DefaultWhatever();
}
}
然后,控制器将获取工厂的一个实例,并让工厂决定实例化哪种类型。用于工厂
您可以采取两种方法:
- 工厂有两种方法,用于定位部件:
public interface IFooFactory
{
IFoo GetFoo(...arguments);
IFoo GetCustomFoo(..arguments);
void ReleaseFoo(IFoo foo);
}
- 在那里使用并封装选择逻辑
container
.Register(
Component.For<IReportFormatter>().ImplementedBy<ReportFormatterWord2003>().Named("word2003"),
Component.For<IReportFormatter>().ImplementedBy<ReportFormatterWord2007>().Named("word2007"),
Component.For<IReportFormatter>().ImplementedBy<ReportFormatterPdf>().Named("pdf"),
Component.For<Func<string, IReportFormatter>>().Instance(container.Resolve<IReportFormatter>),
Component.For<Foo>());
也许不像注册工厂那么容易理解,但却不需要工厂类。为什么不传递一个参数作为“默认”参数来返回最初需要的类型?工厂方法是什么样子的?谢谢Jeff,我认为这里的问题是,我需要通过许多对象将参数向下传递到工厂被注入的点,以便它决定使用哪种类型。我希望避免这种情况。@Si-在不知道您案例的细节的情况下,似乎有必要改变设计,使(假设的)工厂更接近决定工厂产品的对象。至少,将参数保持在与工厂方法调用相同的调用链中应该会使代码更易于遵循和维护。这不是一个坏主意Jeff,然后我可以传递工厂创建的对象而不是参数。
Foo(Func<string, IReportFormatter> reportFormatterFactory)
container.Resolve<IReportFormatter>(string)
reportFormatterFactory("word2007");