gpt4 book ai didi

caSTLe-windsor - 如何配置CaSTLe Windsor以根据提供给Resolve()的参数(“名称”除外)动态选择提供程序

转载 作者:行者123 更新时间:2023-12-04 04:31:13 31 4
gpt4 key购买 nike

我正在尝试学习如何使用温莎城堡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/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com