c# – 如何使用StructureMap在代码中删除ObjectFactory
在使用最新的StructureMap版本(3.1.6.191)升级我们的解决方案后,我收到了很多过时的警告.这些警告来自StructureMap,其中ObjectFactory类将在以后的版本中弃用(4.0).
我正在使用WCF,我们希望使用IInstanceProvider的实现让StructureMap挂钩在WCF管道中: public class StructureMapInstanceProvider : IInstanceProvider 这个类使用ObjectFactory来获取一个实例,当我的容器中没有静态类来解决它时,我们怎么能得到一个类型的实例呢? 解决方法
ObjectFactory正在消失,因为许多人认为它是
anti-pattern从应用程序内部访问容器(称为服务定位器模式).这会将您的代码紧密地耦合到容器,并且难以维护配置,因为确定类所需的依赖项并不容易.
依赖注入与使用服务定位器不同.使用依赖注入,对象图在composition root中的应用程序开始附近得到解析.一旦创建了应用程序,它就没有对IoC容器的引用,因此没有与它紧密耦合.依赖关系在类构造函数中明确定义,因此您无需进一步查看类在注册时所需的依赖关系. 在运行时,您不可避免地需要创建类的实例.为此,您可以转向许多Creational Patterns中的一个(其中Abstract Factory是最常见的并且IInstanceProvider实现),或者,您可以使用容器来创建这些实例的inject a method. 我建议阅读本书Dependency Injection in .NET.有一节(7.3)专门通过实现ServiceHost,ServiceHostFactory和IInstanceProvider来为WCF与??组合根连接. 以下是使用StructureMap的WCF组合根的基本示例(尽管我尚未验证它是否有效). StructureMap注册表 您可以在此处使用容器注册类型.如果您愿意,可以使用多个注册表. public class MyRegistry : Registry { public MyRegistry() { // Register all types this.For<ISomeService>().Use<SomeService>(); } } ServiceHostFactory 这是我们实例化容器并注册类型映射的地方. public class MyServiceHostFactory : ServiceHostFactory { private readonly IContainer container; public MyServiceHostFactory() { this.container = new Container(r => r.AddRegistry<MyRegistry>()); } protected override ServiceHost CreateServiceHost(Type serviceType,Uri[] baseAddresses) { return new MyServiceHost(this.container,serviceType,baseAddresses); } } 的ServiceHost 这是我们注入容器的地方.是的,我们需要至少在一个地方这样做.这里没关系,因为这是插入WCF的组合根的所有部分. public class MyServiceHost : ServiceHost { public MyServiceHost(IContainer container,Type serviceType,params Uri[] baseAddresses) : base(serviceType,baseAddresses) { if (container == null) throw new ArgumentNullException("container"); var contracts = this.ImplementedContracts.Values; foreach (var c in contracts) { c.Behaviors.Add(new MyInstanceProvider(container,serviceType)); } } } IInstanceProvider 我们仍然在应用程序的组合根目录中,因此我们可以注入容器来解析我们的实例. 您的Abstract Factory解析的服务不应该引用容器(既不是静态也不是注入). public partial class MyInstanceProvider : IInstanceProvider,IContractBehavior { private readonly IContainer container; private readonly Type serviceType; public MyInstanceProvider(IContainer container,Type serviceType) { if (container == null) throw new ArgumentNullException("container"); this.container = container; this.serviceType = serviceType; } public object GetInstance(InstanceContext instanceContext,Message message) { return this.GetInstance(instanceContext); } public object GetInstance(InstanceContext instanceContext) { return this.container.GetInstance(this.serviceType); } public void ReleaseInstance(InstanceContext instanceContext,object instance) { // Allow the lifetime management behavior of StructureMap to release dependencies } public void ApplyDispatchBehavior( ContractDescription contractDescription,ServiceEndpoint endpoint,DispatchRuntime dispatchRuntime) { dispatchRuntime.InstanceProvider = this; } } 用法 只需将这些行中的内容添加到.svc文件中,即可注册自定义MyServiceHostFactory以解析您的WCF服务. <%@ ServiceHost Factory = "MyNamespaceName.MyServiceHostFactory,MyAssemblyName" Service = "MyNamespaceName.MyWcfService" %> 使用的参考文献: > Dependency Injection in .NET (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |