首页 文章

如何将流畅的MEF注入WCF

提问于
浏览
3

我正在尝试使用流畅配置的MEF来使用自定义构造函数来提升我的WCF服务 .

如何检查MEF容器是否提供“serviceType” . 例如 . :

public class MyServiceHostFactory : ServiceHostFactory
    {
        private readonly CompositionContainer container;
        public MyServiceHostFactory()
        {
            this.container = MyCompositionRoot.Instance.Container;

        }
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            if (serviceType == ????)
            {
                return new MyServiceHost(container, serviceType, baseAddresses);
            }
            return base.CreateServiceHost(serviceType, baseAddresses);
        }

    }

然后我需要为我的行为添加一个实例提供程序:

public MyServiceHost(CompositionContainer 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)
        {
            // Should I get the service obj here?
            var serviceObj = container.GetExports(serviceType, null, null).First().Value;

            var instanceProvider = new MyInstanceProvider(serviceObj); // ????
            c.Behaviors.Add(instanceProvider);
        }
    }

但我不确定这个实例提供程序应该如何看待(应该将 serviceType 作为参数还是 serviceObj

public partial class MyInstanceProvider : IInstanceProvider,  IContractBehavior

因为在本书(在.NET中使用DI注入)中,该示例使用了一个强耦合的实例提供程序,即 MyServiceType1InstanceProviderMyServiceType2InstanceProvider - 但如果我有许多服务与流畅的mef相连,这将变得乏味 .

2 回答

  • 0

    一种方法是使用 CompositionContainerGetExports方法 . 它返回 IEnumerable<Lazy<Object, Object>> . 如果它包含至少一个元素,则"serviceType"可用 .

    所以检查可以是:

    if (container.GetExports(serviceType, null, null).Any())
    {
         return new MyServiceHost(container, serviceType, baseAddresses);
    }
    

    然后获得导出服务的方法可以是:

    Object seviceObj = container.GetExports(serviceType, null, null).First().Value;
    

    现在的问题是值是System.Object类型,你可以将它强制转换为dynamically或使用 dynamic 关键字(并且松散了编译器的所有帮助) .

  • 1

    WCF服务默认为每个调用实例模式 . 这意味着为每个传入的方法调用实例化了一个新的WCF服务实例 . 这听起来像你想要的是单例实例模式,但如果scability是一个问题,你真的想避免这种情况 .

    我得到的方法是使用每个调用实例模式,但在我同步访问的场景后面有一个静态数据存储 . 这至少允许客户端连接,即使在 Build 连接时数据存储正在使用时它们必须暂时阻塞 .

    有关详细信息,请参阅System.ServiceModel.InstanceContextMode上的MSDN帮助 .

相关问题