C# 如何将IFactory绑定到具体实现?

C# 如何将IFactory绑定到具体实现?,c#,ninject,C#,Ninject,在返回实例之前,我需要一个工厂类做一些工作,因此我有一个工厂方法,如下所示: public Foo Create(string bar, IEnumerable<SomeMetaData> metaData) { var meta = new ObservableCollection<AnotherType>( metaData.Select(e => new AnotherType { ... }).ToLi

在返回实例之前,我需要一个工厂类做一些工作,因此我有一个工厂方法,如下所示:

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));
}
Bind<IFooFactory>().ToFactory<FooFactory>(Func<FooFactoryInstanceProvider>);
(如果有人想评论这个抽象类,我有一个关于CodeReview的问题:)

问题是,在Ninject模块中,我不知道如何告诉Ninject使用特定的混凝土
FooFactory
类:

Bind<IFooFactory>().ToFactory(); // uses an abstract factory that doesn't do what I need
Bind<IFooFactory>().ToFactory<FooFactory>(); // doesn't build
到目前为止还好吗?下一步是什么?

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

而不是:

Bind().ToFactory();
使用:

Bind().To();
如果您正在创建自己的工厂实现,那么是什么驱使您需要使用Ninject工厂扩展中的
ToFactory()
方法呢

编辑1-将factory扩展与自定义实例提供程序一起使用

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

公共类BlueFiftyTwoFoo:Foo{}
Bind().ToFactory(()=>newfoodfactoryinstanceprovider());
自定义实例提供程序根据IFooFactory的'Create()方法参数计算出所需的
Foo
实现的名称,如下所示:

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));
}
Bind<IFooFactory>().ToFactory<FooFactory>(Func<FooFactoryInstanceProvider>);
公共类FooFactoryInstanceProvider:StandardInstanceProvider
{
受保护的重写字符串GetName(MethodInfo MethodInfo,对象[]参数)
{
//收获第一个工厂方法arg,根据需要进行铸造
字符串fooParamOne=(字符串)参数[0];//例如“Blue”
//收获第二个工厂方法arg,根据需要进行铸造
字符串fooParamTwo=(字符串)参数[1];//例如“FiftyTwo”
//操纵这些参数,以生成该参数的**名称**
//您想要的IFoo实现
var fooName=GetFooName(fooParamOne,fooParamTwo);
返回foonName;//例如“BlueFiftyTwoFoo”
}
受保护的重写构造函数参数[]GetConstructorArguments(MethodInfo MethodInfo,object[]参数)
{
//跳过上面使用的参数数量,以获得实现名称
返回base.GetConstructorArguments(methodInfo,arguments).Skip(2).ToArray();
}
私有字符串GetFooName(字符串fooParamOne,字符串fooParamTwo)
{
//做你所做的巫毒
返回fooParamOne+fooParamTwo+Foo;
}
}

此外,我觉得这篇帖子上的答案并不被接受:在这里做什么是正确的-我不想
。InSingletonScope
。。。或者我会吗?顺便说一句,几乎所有Remo的帖子,比如你引用的那篇,都会变成维基文章,并从那里得到更新和改进——值得尝试找到类似的文章,以防万一它有一个update@RubenBartelink谢谢,知道这一点很好——现在我有了,在我最喜欢的Chrome酒吧里,有些东西告诉我他们会在那里停留!不要害怕编辑它们或添加示例-每一个小小的改进都会帮助某人…这是我第一次使用Ninject,阅读文档时我留下的印象是我需要工厂扩展来实现这一点!你的回答完全有道理(看起来这棵树隐藏了森林,我应该试一下!),它似乎在工作,但现在我有了一个ActivationException,绑定了另一个依赖项(我想这应该有它自己的问题)。一旦我解决了这个ActivationException问题,我将能够确认您的答案有效,并接受它。谢谢绝对-我对使用Ninject非常感兴趣,并且在我自己的项目中有一些使用Factorys扩展以及其他一些(Conventions扩展非常酷)的高级场景。如果你发布了一个新的问题链接,请在其中添加评论,我很乐意提供帮助。我还没有完全解决我的问题,但我得到的ActivationException现在已经深入到激活路径中,足以告诉我工厂绑定确实有效;如果我最后再发一个问题,我会通知你的,谢谢!我用一个选项更新了我的答案,该选项用于使用
ToFactory()
方法和自定义实例提供程序。我认为您使用自定义实例提供程序重写
GetType()
方法是错误的。我相信这样做是有原因的,但我看到的大多数示例都覆盖了我在实现中使用的两种方法。我认为这可能也适用于您的场景。我猜这就是你可能遇到激活问题的地方?我最近用Ninject做了很多实验,在这里也问了很多关于它的问题。我还不能让任何人明确地确认,我的理解是,
ToFactory
方法和工厂扩展是支持命名绑定的方便包装器,在这种或那种情况下,要绑定的类型的名称是确定的,因此最终某处有东西在操纵或构建字符串。一定要花一些时间在GitHub的源代码中查看测试。我从那里学到的东西和他们的维基一样多。