我有一组***Converter
继承自的对象,IConverter
目的是从字符串或 XML 反序列化对象:
public interface IConverter
{
object Convert(object value, Type targetType);
}
(我不知道编译时的类型,所以我不能在这里使用泛型)。
我使用 aConvertsAttribute
来标记转换器可以转换的类型,然后将其加倍为 Ninject ConstraintAttribute
:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class ConvertsAttribute : ConstraintAttribute
{
public Type TargetType { get; private set; }
public ConvertsAttribute(Type t)
{
TargetType = t;
}
public override bool Matches(IBindingMetadata metadata)
{
return metadata.Has("Converts") && metadata.Get<Type>("Converts") == this.TargetType;
}
}
[Converts(typeof(Int32))]
[Converts(typeof(Single))]
[Converts(typeof(String))]
[Converts(typeof(Double))]
public class BasicConverter : IConverter
{
public object Convert(object value, Type targetType)
{
return System.Convert.ChangeType(value, targetType);
}
}
在我的序列化模块中绑定转换器时,我在“Converts”下附加了类型元数据:
private void BindConverter(Type typeInfo)
{
var converterAttributes = typeInfo.GetCustomAttributes(typeof(ConvertsAttribute), true);
foreach (var attribute in converterAttributes.Cast<ConvertsAttribute>())
Bind<IConverter>().To(typeInfo).WithMetadata("Converts", attribute.TargetType);
}
解析类型时,我可以在容器中查询转换特定类型的转换器:
private IConverter GetConverter(Type t)
{
return converterKernel.Get<IConverter>(metadata => t == metadata.Get<Type>("Converts"));
}
但是,这意味着我必须在我的类构造函数中获取 IKernel 实例并在运行时查询它,这是我想避免的(闻起来我可以查询我的 convertKernel 以获取非 IConverter 对象)。
我可以简单地IEnumerable<IConverter>
在构造函数中请求,然后在每个转换器的类型上查询 ConvertsAttribute,但我想知道是否有办法利用 Ninject 的元数据为我执行此操作......我可以IEnumerable<IConverter>
在构造函数中请求附加元数据吗?在这种情况下,我想构建一个类型的字典,IDictionary<Type, IConverter>
这意味着我不必查询容器本身。