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);
        }
    }

但我不确定此实例提供程序的外观(应该将 aserviceType作为参数还是serviceObj?

public partial class MyInstanceProvider : IInstanceProvider,  IContractBehavior

因为在本书(.NET 中的 DI 注入)中,该示例使用了强耦合实例提供程序,即MyServiceType1InstanceProvider, MyServiceType2InstanceProvider- 但是如果我有许多服务与流利的 mef 挂钩,那将变得乏味。

4

2 回答 2

1

一种方法使用CompositionContainer. 它返回一个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;

现在的问题是 value 是 System.Object 类型,你可以动态转换它还是使用dynamic关键字(并失去编译器的所有好帮助)。

于 2013-06-28T13:21:55.430 回答
0

WCF 服务默认为按调用实例模式。这意味着每次传入的方法调用都会实例化 WCF 服务的新实例。听起来您想要的是单例实例模式,但如果可伸缩性是一个问题,您真的想避免这种情况。

我解决这个问题的方法是使用每次调用实例模式,但在我同步访问的幕后有一个静态数据存储。这至少允许客户端进行连接,即使在建立连接后他们必须在数据存储正在使用时暂时阻塞。

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

于 2013-07-10T08:18:02.180 回答