- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试学习如何使用温莎城堡IoC,并且在理解如何配置一些需要动态解析的对象方面遇到一些困难。基本上,我有几个IDataSource的实现,我需要根据如何配置特定的“数据源”来选择要使用的实现。因此,我可能有很多数据源配置为使用3种实现之一。我的期望是,依赖代码将依赖于工厂方法,当提供“数据源ID”以及数据源实现所需的依赖项(IPrincipal)时,该工厂方法将为它们提供正确的IDataSource。
我正在为如何正确编写Windsor的注册代表而苦苦挣扎。以下大致是我所得到的。我正在尝试使用DynamicParameters
方法(可能使用的不是正确的方法)来执行找出要使用哪种实现的逻辑,然后调用Resolve
提取特定版本。但是我不知道如何返回解析的对象,因为DynamicParameters
期望的是ComponentReleasingDelegate
,我认为这意味着它应该类似于return k => { k.ReleaseComponent(dataSource); }
。但是,如何将已获取的数据源返回给容器以返回给调用者呢?
struct DataSourceInfo {
string Id;
string ProviderType;
}
interface ICatalog : IDictionary<string /* Id */, DataSourceInfo> {
/* ... */
}
class Catalog : ICatalog {
/* implement dictionary which looks up DataSourceInfo from their string id */
}
interface IDataSource { /* ... */ }
class Source1 : IDataSource {
Source1(string id, IPrincipal principal) { /* ... */ }
}
class Source2 : IDataSource {
Source2(string id, IPrincipal principal) { /* ... */ }
}
/* ... */
/* ... inside Windsor configuration section */
container.Register(Component.For<ICatalog>().LifeStyle.Singleton.ImplementedBy<Catalog>());
// Default service provider is a factory method which uses the string (data source id)
// and looks up the DataSourceInfo from the ICatalog. It then uses info.ProviderType
// to request IoC to resolve that specific implementation and passes in "id" and "principal"
// to be used to resolve the dependencies of the implementation
container.Register(Component.For<IDataSource>().LifeStyle.Transient
.DynamicParameters((kernel, context, args) => {
if (args == null || !args.Contains("id") || !(args["id"] is string)) throw ApplicationException("bad args");
var id = (string)args["id"];
var catalog = kernel.Resolve<ICatalog>();
DataSourceInfo info;
try { info = catalog[id]; } finally { kernel.ReleaseComponent(catalog); }
// Now resolve the actual IDataSource
var dataSource = kernel.Resolve<IDataSource>(info.ProviderType, args);
// How do I return dataSource???
});
// Now register the actual implementations
container.Register(Component.For<IDataSource>().LifeStyle.Transient.ImplementedBy<Source1>().Named("Source1"));
container.Register(Component.For<IDataSource>().LifeStyle.Transient.ImplementedBy<Source2>().Named("Source2"));
/* ... */
/* some application startup code which configures some data sources */
class AppConfigurer {
AppConfigurer(ICatalog catalog) {
catalog["sourceA"] = new DataSourceInfo() { Id = "sourceA", ProviderType = "Source1" }; // data sourceA is provided by Source1 class
catalog["sourceB"] = new DataSourceInfo() { Id = "sourceB", ProviderType = "Source2" }; // data sourceB is provided by Source2 class
catalog["sourceC"] = new DataSourceInfo() { Id = "sourceC", ProviderType = "Source2" }; // data sourceC is provided by Source2 class
catalog["sourceD"] = new DataSourceInfo() { Id = "sourceD", ProviderType = "Source2" }; // data sourceD is provided by Source2 class
catalog["sourceE"] = new DataSourceInfo() { Id = "sourceE", ProviderType = "Source1" }; // data sourceE is provided by Source1 class
}
}
// Here is where I actually want to use IDataSources, and I do not want to know all the business about IDataSourceInfo. I just know a dataSourceId and an IPrincipal and want to get an IDataSource to work with.
class Dependant {
Dependant (Func<string, IPrincipal, IDataSource> factory) {
var sourceA = factory("sourceA", somePrincipal); // sourceA.GetType() == typeof(Source1)
var sourceB = factory("sourceB", somePrincipal); // sourceB.GetType() == typeof(Source2)
var sourceC = factory("sourceC", somePrincipal); // sourceC.GetType() == typeof(Source2)
}
}
DynamicParameters
切换到
UsingFactoryMethod
,我可以做我想要的事情。但是我一直认为这是错误的,因为现在如果我执行
container.ResolveAll()
,我真的希望它跳过工厂方法,但是我不知道如何使其执行该操作。
最佳答案
为什么不只创建一个自定义组件类型选择器,然后根据该选择器决定加载哪个组件?
Typed Factory Facility - interface-based factories
关于caSTLe-windsor - 如何配置CaSTLe Windsor以根据提供给Resolve()的参数(“名称”除外)动态选择提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5876331/
我在调用 Resolve 时遇到异常: KernelException: Could not instantiate custom activator Inner Exception: {"Const
我的应用程序使用“SignalR”客户端/服务器通信框架。如果您不熟悉它,服务器端应用程序通常包含一个或多个“集线器”类(类似于 asmx 网络服务),每个类都提供可由客户端调用的方法。在启动期间,客
假设我有这样的组件 public class MyComponent { public MyComponent(string name) { } } 我基本上想让提供的构造函数
在 CaSTLe Windsor 场景中,我想检查我的容器是否注册了某个服务,并且基本上做 if (container.HasComponentFor()) { // resolve serv
我想知道是否有一些最佳实践来实现我需要的功能。 我有一个 Web 应用程序,它在启动期间通过反射扫描某些程序集(插件)并针对公共(public)内核注册它们的依赖项。 外部库可能需要相同的依赖项。 例
我想知道是否有一些最佳实践来实现我需要的功能。 我有一个 Web 应用程序,它在启动期间通过反射扫描某些程序集(插件)并针对公共(public)内核注册它们的依赖项。 外部库可能需要相同的依赖项。 例
是否有关于如何使用 CaSTLe Windsor 的自动事务管理的任何简单示例? documentation似乎缺少一些信息。我看到有用于 nHibernate、ActiveRecord 等的工具……
考虑这个例子: public class Factory { private List subFactories; public Factory(Lis
我正在将我们的项目从 .Net 2 升级到 .Net4.5,同时我将尽可能多的引用推送到 NuGet 并确保版本是最新的。 我在运行其中一项测试时遇到问题 测试类: public cl
当我开始使用 Windsor 时,我认为 DI 会很简单。现在它让我越来越困惑。 在我看来,存储库是一个具有单例生命周期的类。我应该有一个 FooRepository 实例来在应用程序的生命周期内将
我有一个接口(interface) ISession,其实例由不同的 session 工厂生成,具体取决于类所属的命名空间。 我的组件注册示例: IWindsorContainer container
我有一个看似简单的用例。有一个 ICsvReader 组件。让我们在这里简单地将它命名为 Reader。我们加载了一组已知的 CSV 文件,其中一些有标题,有些没有。目前有多个阅读器:Reader_S
这是我在 Global.asax 中的代码 WindsorContainer container = new WindsorContainer(); container.Register(Compo
在使用 ArrayResolver 时,如果我注册了一个接口(interface)的多个实现和一个依赖于所述接口(interface)数组的类,我希望数组解析器注入(inject)所有可以成功解析的接
有没有人有一些使用城堡 Windsor InstallerFactory 来订购安装程序的示例代码? 似乎无法在文档或其他地方找到它。 干杯 最佳答案 您只能使用 InstallerFactory与
documentation 中有说明你应该总是让拦截器 transient 。如果我有这个示例代码; //register interceptor container.Register(Classes
我有一点问题。我在 CaSTLe Windsor IOC Container 工作。现在我想做的只是弄乱一些 AOP 原则,而我特别想做的是基于方法名称执行一些日志记录。我一直在研究拦截器,目前我正在
有人对使用 CaSTLe DynamicProxy 拦截属性的更好方法有什么建议吗? 具体来说,我需要我正在拦截的 PropertyInfo,但它不是直接在 IInvocation 上,所以我要做的是
使用 ArrayResolver 时,如果我注册了多个实现相同接口(interface)的依赖项,并且我已经注册了依赖于这些依赖项数组的类,那么人们会期望 ServiceOverrides 受到尊重并
如何使用 Windsor 容器将 appSettings 条目的值(来自 app.config 或 web.config)注入(inject)服务?如果我想将 Windsor 属性的值注入(injec
我是一名优秀的程序员,十分优秀!