我正在使用Ninject Factory扩展程序。是否可以使自动创建的ConstructorArguments具有inherit = true?我希望以下工作:
kernel.Bind<IFactory>.ToFactory();
IFactory是:
public interface IFactory {
View GetView(object param);
}
和param被提交给View:s依赖项(View不需要它)。
我知道我可以自己实施工厂,但我想知道Factory Extension是否有开箱即用的(无证件)支持?
答案 0 :(得分:1)
不,开箱即用不支持。 只需要开箱即用的两件事:
IFactory
方法名称以Get
开头时)您可以做的是编写自己的自定义IInstanceProvider
。
请参阅this answer,其中介绍了如何应用自定义IInstanceProvider
。
IInstanceProvider
是您放置此类(自定义)内容的地方。
我们所做的是编写一个通用实例提供程序,它执行一些反射来检测几个自定义属性,然后将其解释为允许多个事项(继承,在名称匹配时注入,在类型匹配时注入,约束分辨率,确定将实例化哪个类型,添加请求的参数,...)
然而,对于单个应用程序(不是在一个软件中,而是在使用它的一个代码中),它可能不值得。我自己实施工厂。
IInstanceProvider
,其中包含继承的ConstructorArgument
public class InheritingConstructorArgumentsInstanceProvider : StandardInstanceProvider
{
protected override IConstructorArgument[] GetConstructorArguments(
MethodInfo methodInfo,
object[] arguments)
{
return methodInfo
.GetParameters()
.Select((parameter, index) =>
new ConstructorArgument(
parameter.Name,
arguments[index],
true))
.Cast<IConstructorArgument>()
.ToArray();
}
}
然后绑定如下:
kernel
.Bind<IFactory>()
.ToFactory(() => new InheritingConstructorArgumentsInstanceProvider());
这里是完整的代码:
namespace NinjectTest.CustomFactory
{
using System.Linq;
using System.Reflection;
using FluentAssertions;
using Ninject;
using Ninject.Extensions.Factory;
using Ninject.Parameters;
using Xunit;
public class InheritingConstructorArgumentsInstanceProvider : StandardInstanceProvider
{
protected override IConstructorArgument[] GetConstructorArguments(
MethodInfo methodInfo,
object[] arguments)
{
return methodInfo
.GetParameters()
.Select((parameter, index) =>
new ConstructorArgument(
parameter.Name,
arguments[index],
true))
.Cast<IConstructorArgument>()
.ToArray();
}
}
public class Foo
{
public Bar Bar { get; private set; }
public Foo(Bar bar)
{
Bar = bar;
}
}
public class Bar
{
public string Id { get; private set; }
public Bar(string id)
{
Id = id;
}
}
public interface IFactory
{
Foo Create(string id);
}
public class Test
{
[Fact]
public void Foo()
{
var kernel = new StandardKernel();
kernel
.Bind<IFactory>()
.ToFactory(() => new InheritingConstructorArgumentsInstanceProvider());
const string expectedId = "Hello You!";
kernel.Get<IFactory>().Create(expectedId).Bar.Id.Should().Be(expectedId);
}
}
}
答案 1 :(得分:1)
我实现了一个自定义提供程序,它非常简单:
public class InheritingConstructorArgumentsInstanceProvider : StandardInstanceProvider
{
protected override IConstructorArgument[] GetConstructorArguments(
MethodInfo methodInfo, object[] arguments)
{
var parameters = methodInfo.GetParameters();
var constructorArguments = new IConstructorArgument[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
constructorArguments[i] = new ConstructorArgument(
parameters[i].Name, arguments[i], true);
}
return constructorArguments;
}
}
感谢你让我朝着正确的方向前进!