使用 Ninject 上下文绑定时如何检索属性和特性?
How can I retrieve the attribute and the properties when using Ninject contextual binding?
我有构造函数
[ReadFromFile(@"C:\SampleData\login.json")]
public AccountController(IReadRepository<LoginMockDataModel> repository, string filePath) : base(repository)
{
}
该属性包含 属性 "FilePath".
public string FilePath {get;set;}
我想检索 "FilePath" 的值,在上述情况下为 "C:\SampleData\login.json"。
是否可以使用 Ninject 的 IContext 检索值?
想法是检索 属性 的值,然后在绑定中使用它,如下所示:
// FileReadRepo contains a constructor with the argument "filePath"
// which will need a string passed to it which I am trying to retrieve
// from the Attribute above
Bind(typeof(IReadRepository<>)).To(typeof(FileReadRepo<>))
.WhenMemberHas<ReadFromFileAttribute>()
.WithConstructorArgument("filePath", CheckAttributePath);
其中 CheckAttributePath 将是委托:
private object CheckAttributePath(IContext arg)
{
throw new NotImplementedException();
}
我不确定如何获取属性值。
访问 AccountController
的构造函数是通过 IContext.Request.Target.Member
完成的。所以这有效:
private static object CheckAttributePath(IContext context)
{
var attributes = context.Request.Target.Member
.GetCustomAttributes(typeof(ReadFromFileAttribute), false);
return ((ReadFromFileAttribute)attributes[0]).Path;
}
完整的测试代码(使用 xunit 和 FluentAssertions):
using System;
using Ninject;
using Ninject.Activation;
using Xunit;
using FluentAssertions;
public interface IReadRepository<T>
{
string FilePath { get; }
}
public class FileReadRepo<T> : IReadRepository<T>
{
private readonly string filePath;
public FileReadRepo(string filePath)
{
this.filePath = filePath;
}
public string FilePath { get { return this.filePath; } }
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
public class ReadFromFileAttribute : Attribute
{
public readonly string Path;
public ReadFromFileAttribute(string path)
{
this.Path = path;
}
}
public class AccountController
{
public readonly IReadRepository<string> Repository;
[ReadFromFile(IntegrationTest.SampleFilePath)]
public AccountController(IReadRepository<string> repository)
{
this.Repository = repository;
}
}
public class IntegrationTest
{
public const string SampleFilePath = @"C:\SampleData\login.json";
[Fact]
public void Test()
{
var kernel = new StandardKernel();
kernel.Bind(typeof(IReadRepository<>)).To(typeof(FileReadRepo<>))
.WhenMemberHas<ReadFromFileAttribute>()
.WithConstructorArgument("filePath", CheckAttributePath);
kernel.Get<AccountController>().Repository.FilePath.Should().Be(SampleFilePath);
}
private static object CheckAttributePath(IContext context)
{
var attributes = context.Request.Target.Member.GetCustomAttributes(
typeof(ReadFromFileAttribute), false);
return ((ReadFromFileAttribute)attributes[0]).Path;
}
}
我有构造函数
[ReadFromFile(@"C:\SampleData\login.json")]
public AccountController(IReadRepository<LoginMockDataModel> repository, string filePath) : base(repository)
{
}
该属性包含 属性 "FilePath".
public string FilePath {get;set;}
我想检索 "FilePath" 的值,在上述情况下为 "C:\SampleData\login.json"。
是否可以使用 Ninject 的 IContext 检索值?
想法是检索 属性 的值,然后在绑定中使用它,如下所示:
// FileReadRepo contains a constructor with the argument "filePath"
// which will need a string passed to it which I am trying to retrieve
// from the Attribute above
Bind(typeof(IReadRepository<>)).To(typeof(FileReadRepo<>))
.WhenMemberHas<ReadFromFileAttribute>()
.WithConstructorArgument("filePath", CheckAttributePath);
其中 CheckAttributePath 将是委托:
private object CheckAttributePath(IContext arg)
{
throw new NotImplementedException();
}
我不确定如何获取属性值。
访问 AccountController
的构造函数是通过 IContext.Request.Target.Member
完成的。所以这有效:
private static object CheckAttributePath(IContext context)
{
var attributes = context.Request.Target.Member
.GetCustomAttributes(typeof(ReadFromFileAttribute), false);
return ((ReadFromFileAttribute)attributes[0]).Path;
}
完整的测试代码(使用 xunit 和 FluentAssertions):
using System;
using Ninject;
using Ninject.Activation;
using Xunit;
using FluentAssertions;
public interface IReadRepository<T>
{
string FilePath { get; }
}
public class FileReadRepo<T> : IReadRepository<T>
{
private readonly string filePath;
public FileReadRepo(string filePath)
{
this.filePath = filePath;
}
public string FilePath { get { return this.filePath; } }
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
public class ReadFromFileAttribute : Attribute
{
public readonly string Path;
public ReadFromFileAttribute(string path)
{
this.Path = path;
}
}
public class AccountController
{
public readonly IReadRepository<string> Repository;
[ReadFromFile(IntegrationTest.SampleFilePath)]
public AccountController(IReadRepository<string> repository)
{
this.Repository = repository;
}
}
public class IntegrationTest
{
public const string SampleFilePath = @"C:\SampleData\login.json";
[Fact]
public void Test()
{
var kernel = new StandardKernel();
kernel.Bind(typeof(IReadRepository<>)).To(typeof(FileReadRepo<>))
.WhenMemberHas<ReadFromFileAttribute>()
.WithConstructorArgument("filePath", CheckAttributePath);
kernel.Get<AccountController>().Repository.FilePath.Should().Be(SampleFilePath);
}
private static object CheckAttributePath(IContext context)
{
var attributes = context.Request.Target.Member.GetCustomAttributes(
typeof(ReadFromFileAttribute), false);
return ((ReadFromFileAttribute)attributes[0]).Path;
}
}