如何使用MEF扩展WCF数据服务和实体框架模型

时间:2013-05-03 08:39:35

标签: asp.net-mvc entity-framework entity-framework-5 mef wcf-data-services

我正在使用一个公开的WCF DataService类来公开一个简单的实体框架模型。该服务包含在发布到IIS的简单Web应用程序中。没什么好看的,对吧!

我正在尝试构建MSDN描述的方式

  

请求和申请范围
  在MVC应用程序中创建的零件实例   存在于两个范围之一:请求范围或应用程序   范围。默认情况下,在Web期间创建的零件实例   请求在请求范围内。在的部分实例   相同的请求是共享的,因此如果多个部分导入给定的   部分地,所有导入者都接收对同一实例的引用。每个网站   请求有自己的范围,因此在一个请求中创建的部分永远不会   用于填写另一个请求中的导入。当请求结束时,它   销毁相关范围,并为其创建任何零件   销毁。部署实现IDisposable对象的部件。   这可以确保敏感资源,例如数据库连接,   正确关闭。有时,您可能不想创建零件   每个请求的实例(例如,当您实现应用程序范围时   高速缓存)。在这些情况下,您可以强制在中创建零件   应用ApplicationScoped属性的应用程序范围。部分   在应用程序范围内始终由应用程序中的所有请求共享。   应用范围的一部分可能取决于其他部分   应用范围仅适用于其导入。应用范围中的部件   必须小心保持线程安全。

其中一个主要问题是我不知道在哪里创建RequestScope容器。我认为RequestScope容器应该在DataService类之外构建,对吗?

任何帮助预测

1 个答案:

答案 0 :(得分:1)

万一你需要类似的东西,我有一个工作的解决方案,我在这里发布

public class MefDataServiceHostFactory : DataServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(
            Type serviceType, Uri[] baseAddresses)
        {
            ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
            host.Description.Behaviors.Add(new MefServiceBehavior());
            return host;
        }
    }

    public class MefInstanceProvider : IInstanceProvider
    {
        #region fields

        private readonly Type _serviceType;
        private IDependencyScope _diScope;

        #endregion

        #region ctor

        public MefInstanceProvider(Type serviceType)
        {
            _serviceType = serviceType;
        }

        #endregion

        public object GetInstance(InstanceContext instanceContext)
        {
            return GetInstance(instanceContext, null);
        }

这是重要的部分,可以使用MEF或IOC。

        public object GetInstance(InstanceContext instanceContext, Message message)
        {
           _diScope = GlobalConfiguration.Configuration.DependencyResolver.BeginScope();
            return _diScope.GetService(_serviceType);
        }

        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {
           if (_diScope != null) _diScope.Dispose();
        }
    }

获取新实例并处理请求

    public class MefServiceBehavior : IServiceBehavior
    {
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                var cd = cdb as ChannelDispatcher;
                if (cd != null)
                {
                    foreach (EndpointDispatcher ed in cd.Endpoints)
                    {
                        ed.DispatchRuntime.InstanceProvider = new MefInstanceProvider(serviceDescription.ServiceType);
                    }
                }
            }
        }

        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
                                         Collection<ServiceEndpoint> endpoints,
                                         BindingParameterCollection bindingParameters)
        {
        }

        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }
    }

在svc文件中注册自定义工厂

<%@ServiceHost Service="DataService"
               Factory="MefDataServiceHostFactory"
               language=c# Debug="true" %>

或添加新的服务路线。

routes.Add(new ServiceRoute(string.Empty, new MefDataServiceHostFactory(), typeof (DataService)));

快乐的编码!