StructureMap通过注入而不是服务定位来解析依赖在我的项目中,我使用程序集扫描器注册了许多ISerializers实现。FWIW这是注册我的ISerializers的代码然后正确注册ISerializer(...ISerializer)Scopedas:TransientJsonSerializerConfiguredInstanceof...JsonSerializerBsonSerializerConfiguredInstanceof...BsonSerializer等。目前,我唯一能弄清楚如何解决的方法我想要的序列化程序是使用硬编码服务位置调用jsonSerializer=ObjectFactory.GetNamedInstance("JsonSerializer");现在我知道我特别想要jsonSerializer的类,所以没有办法配置规则或类似的东西来说明ISerializer根据属性名称连接命名实例吗?那么我可以MySomeClass(ISerializerjsonSerializer,...)StructureMap正确处理这种情况吗?或者我处理这个错误,也许我应该只注册实现ISerializer的具体类型,然后专门使用MySomeClass(JsonSerializerjsonSerializer,...)来处理具体类内容的这些方面?当您进行依赖注入并且需要能够创建给定接口的特定类型的实例时,建议的解决方案是创建一个专用的工厂类。这允许您使用命名参数而无需实际注入到容器中。示例这是您要注入的抽象类型:publicinterfaceISerializerFactory{ISerializerGetSerializer(stringname);这是具体的类型,它使用你的容器(StructureMap):然后你的类将如下所示:publicclassMyClass{privatereadonlyISerializerFactoryserializerFactory;publicMyClass(ISerializerFactoryserializerFactory){if(serializerFactory==null)thrownewArgumentFactoryNullException("tory"serializer);this.serializerFactory=serializerFactory;}publicstringSerializeSomeData(MyDatadata){ISerializerserializer=serializerFactory.GetSerializer("Json");返回序列化程序。序列化(数据);我写这个是为了传递“Json”而不是“JsonSerializer”,它不会自动运行。但我认为你应该更改你的注册名称以删除多余的“Serializer”后缀(我们已经知道它是一个序列化程序,因为我们要求ISerializer).换句话说,创建这样的方法:privatestaticstringExtractSerializerName(TypeserializerType){stringtypeName=serializerType.Name;intsuffixIndex=typeName.IndexOf("Serializer");返回(后缀索引>=0)?typeName.Substring(0,suffixIndex-1):typeName;}并注册如下:scanner.AddAllTypesOf().NameBy(type=>ExtractSerializerName(type));然后你可以使用字符串“Json”来创建它而不是“JsonSerializer”,它看起来会少一点丑陋并且感觉不那么耦合。如果您不喜欢硬编码字符串,您可以做的另一件事是为您的工厂创建一个枚举:publicenumSerializationFormat{Json,Bson,Xml};publicinterfaceISerializerFactory{ISerializerGetSerializer(SerializationFormat格式);}publicclassStructureMapSerializerFactory:ISerializerFactory{publicISerializerGetSerializer(SerializationFormatformat){returnObjectFactory.GetNamedInstance(format.ToString());因此,与其这样写:ISerializerserializer=serializerFactory.GetSerializer);("JThis:ISerializerserializer=serializerFactory.GetSerializer(SerializationFormat.Json);从长远来看,这将不易出错。这可能更容易维护从长远来看,因为如果您开始更改序列化程序的类名和/或名称不一致,那么您可以用switch语句替换简单的ToString()并将枚举值实际映射到您正在注册的类名称。我可能会把所有这些代码——包括你问题中的自动注册代码——放在同一个命名空间,甚至同一个代码文件中,以明确代码都是相互依赖的。据我所知,这不是程序集扫描功能的目的。当单个程序集具有许多不同接口(例如,IRepository、IRepository等)的实现时,它更有用。因此,例如,当您引用测试程序集时,您正在注入测试存储库,而在生产中,您正在注入实体框架存储库。在您的情况下,您的示例看起来根本没有注入依赖项。换句话说,当你写ObjectFactory.GetNamedInstance("JsonSerializer");由于字符串是硬编码的,您仍然依赖于Json序列化程序,并且从该调用返回一些其他类型的序列化程序没有意义。我无法确切地告诉您使用StructureMap可以完成什么,但是如果您需要根据某些运行时条件返回特定的序列化程序,您可以看一下ConditionalConstruction。另一方面,这样的开关听起来并不合适,因此您绝对应该考虑摆脱它。毕竟,上面的代码真的没有什么不同newJsonSerializer();StructureMap是一个很棒的工具,但并不是每个项目都需要它。祝你好运!由于您的代码假定它正在获取JsonSerializer,因此创建一个只有JsonSerializer实现的新IJsonSerializer接口。任何需要JsonSerializer的类都应该接受IJsonSerializer。如果仍然需要ISerializer接口在所有序列化程序中通用,则IJsonSerializer可以用作标记接口。或者,您可以在向StructureMap注册时将特定的ISerializer实现绑定到您的类。x.For().Use(c=>newMySomeClass(c.GetInstance()));我很好奇。ISerializer本身有什么价值?让我们从一个特定的实现转移到一个或多个在运行时选择的实现。如果您的类型依赖于特定类型的序列化程序,则依赖它(IJsonSerializer)。这需要在容器中注册该类型的默认实例。但是,如果您更多地将ISerializers视为一种策略,您将注册所有ISerializers,然后依赖它们的数组,而StructureMap将推入所有已注册ISerializers的数组。然后使用这些序列化器的类负责选择使用哪一个。在策略场景中,您可能需要序列化程序上的一些元数据供协调类使用以区分它们。恕我直言,这不应该是容器配置,例如注册类型上的名称,而是实现本身的元数据。以上是C#学习教程:StructureMap通过注入而不是服务定位的方式解析依赖共享的所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注。本文来自网络收集,不代表侵权,请点击右边联系管理员删除。如需转载请注明出处:
