当您进行依赖注入并且需要能够创建给定接口的特殊类型实例时,推荐的解决方案是创建 specialized 工厂类。这允许您在不实际注入容器的情况下使用命名参数。
示例
这是您将要注入的抽象类型:
public interface ISerializerFactory
{
ISerializer GetSerializer(string name);
}
这是使用容器(StructureMap)的具体类型:
public class StructureMapSerializerFactory : ISerializerFactory
{
public ISerializer GetSerializer(string name)
{
return ObjectFactory.GetNamedInstance<ISerializer>(name);
}
}
那么你的类将如下所示:
public class MyClass
{
private readonly ISerializerFactory serializerFactory;
public MyClass(ISerializerFactory serializerFactory)
{
if (serializerFactory == null)
throw new ArgumentNullException("serializerFactory");
this.serializerFactory = serializerFactory;
}
public string SerializeSomeData(MyData data)
{
ISerializer serializer = serializerFactory.GetSerializer("Json");
return serializer.Serialize(data);
}
}
我已经写了这个传递“Json”而不是“JsonSerializer”,它不会自动工作。但我认为您应该更改注册名称以消除多余的“Serializer”后缀(我们已经知道它是一个序列化程序,因为我们要求的是ISerializer)。换句话说,创建一个这样的方法:
private static string ExtractSerializerName(Type serializerType)
{
string typeName = serializerType.Name;
int suffixIndex = typeName.IndexOf("Serializer");
return (suffixIndex >= 0) ?
typeName.Substring(0, suffixIndex - 1) : typeName;
}
并像这样注册它:
scanner.AddAllTypesOf<ISerializer>().NameBy(type => ExtractSerializerName(type));
那么你可以直接使用字符串“Json”来创建它,而不是“JsonSerializer”,这样看起来会不那么难看,感觉不那么耦合。
如果您不喜欢硬编码的字符串,那么您可以做的另一件事是为您的工厂创建一个枚举:
public enum SerializationFormat { Json, Bson, Xml };
public interface ISerializerFactory
{
ISerializer GetSerializer(SerializationFormat format);
}
public class StructureMapSerializerFactory : ISerializerFactory
{
public ISerializer GetSerializer(SerializationFormat format)
{
return ObjectFactory.GetNamedInstance<ISerializer>(format.ToString());
}
}
所以不要写这个:
ISerializer serializer = serializerFactory.GetSerializer("Json");
你可以改写这个:
ISerializer serializer =
serializerFactory.GetSerializer(SerializationFormat.Json);
从长远来看,这将不太容易出错。
从长远来看,这可能更易于维护,因为如果您开始更改序列化程序的类名和/或名称不一致,那么您可以将简单的 ToString() 替换为 switch 语句并实际映射您正在注册的类名的枚举值。
我可能会将所有这些代码(包括您问题中的自动注册代码)放在同一个命名空间,甚至是同一个代码文件中,以清楚地表明这些部分都是相互依赖的。