gpt4 book ai didi

c# - 如何将 IFactory 绑定(bind)到具体实现?

转载 作者:行者123 更新时间:2023-11-30 12:11:10 24 4
gpt4 key购买 nike

我需要一个工厂类在返回一个实例之前做一些工作,所以我有一个这样的工厂方法:

public Foo Create(string bar, IEnumerable<SomeMetaData> metaData)
{
var meta = new ObservableCollection<AnotherType>(
metaData.Select(e => new AnotherType { ... }).ToList());

return Create(new ConstructorArgument("bar", bar),
new ConstructorArgument("metaData", meta));
}

具体的工厂类派生自一个基本工厂,它让我省去了实际的布线,以防你想知道 IResolutionRoot 在哪里已经走了:

public abstract class FactoryBase<T> where T : class
{
private IResolutionRoot _resolutionRoot;
protected FactoryBase(IResolutionRoot resolutionRoot)
{
_resolutionRoot = resolutionRoot;
}

protected T Create(params IParameter[] parameters)
{
return _resolutionRoot.Get<T>(parameters);
}
}

(我在 CodeReview 上有一个关于这个抽象类的问题,如果有人想对此发表评论:https://codereview.stackexchange.com/questions/25038/are-there-side-effects-to-having-a-generic-ninject-factory)

问题是在 NinjectModule 中,我不知道如何告诉 Ninject 使用那个特定的具体 FooFactory类:

Bind<IFooFactory>().ToFactory(); // uses an abstract factory that doesn't do what I need
Bind<IFooFactory>().ToFactory<FooFactory>(); // doesn't build

我相信我需要的是这样的东西:

Bind<IFooFactory>().ToFactory<FooFactory>(Func<FooFactoryInstanceProvider>);

我需要做什么才能提供这个 InstanceProvider ?可能这只是我对Func<T>的误解但我发现http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/对此太含糊了。

我想到了这个:

public class FooFactoryInstanceProvider : StandardInstanceProvider
{
protected override Type GetType(MethodInfo methodInfo, object[] arguments)
{
return typeof(FooFactory);
}
}

到目前为止还好吗?下一步是什么?

最佳答案

如果您已经努力制作自己的 FooFactory 实现,为什么不以非工厂方式绑定(bind)到它:

代替:

Bind<IFooFactory>().ToFactory<FooFactory>();

使用:

Bind<IFooFactory>().To<FooFactory>();

如果您要创建自己的工厂实现,究竟是什么驱使您需要使用 Ninject 工厂扩展中的 ToFactory() 方法?

编辑 1 - 将工厂扩展与自定义实例提供程序结合使用

这样,您就可以将用于解析所需的 Foo 的逻辑放入自定义实例提供程序中。如果您可以获得与 Foo 实现的名称相匹配的逻辑,那么您就成功了。

public class BlueFiftyTwoFoo : Foo { }

Bind<IFooFactory>().ToFactory(() => new FooFactoryInstanceProvider());

自定义实例提供程序根据您的 IFooFactory 的 `Create() 方法参数计算出您想要的 Foo 实现的名称,如下所示:

public class FooFactoryInstanceProvider : StandardInstanceProvider
{
protected override string GetName(MethodInfo methodInfo, object[] arguments)
{
// harvest the 1st factory method arg, cast as appropriate
string fooParamOne = (string)arguments[0]; // ex. "Blue"

// harvest the 2nd factory method arg, cast as appropriate
string fooParamTwo = (string)arguments[1]; // ex. "FiftyTwo"

// manipulate the params to come up with the **Name** of the
// IFoo implementation you want
var fooName = GetFooName(fooParamOne, fooParamTwo);

return fooName; // ex. "BlueFiftyTwoFoo"
}

protected override ConstructorArgument[] GetConstructorArguments(MethodInfo methodInfo, object[] arguments)
{
// skip the number of params you're using above to come up with the implementation name
return base.GetConstructorArguments(methodInfo, arguments).Skip(2).ToArray();
}

private string GetFooName(string fooParamOne, string fooParamTwo)
{
// do that voodoo that you do
return fooParamOne + fooParamTwo + "Foo";
}
}

关于c# - 如何将 IFactory 绑定(bind)到具体实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15978532/

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