Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 尝试向我的WCF服务添加IoC支持_C#_Wcf_Ioc Container - Fatal编程技术网

C# 尝试向我的WCF服务添加IoC支持

C# 尝试向我的WCF服务添加IoC支持,c#,wcf,ioc-container,C#,Wcf,Ioc Container,我正在尝试向REST WCF服务(Windows Server 2008)添加IoC支持。我不熟悉这一点,并遵循以下视频中提供的说明: 该视频介绍了一些类,这些类帮助我在公开WCF端点的同时启动并运行StructureMap的IoC。我已经在这篇文章的末尾发布了所有代码 当我运行代码时,自定义类StructureMapServiceHost在StructureMapServiceHost(类型serviceType,参数Uri[]baseAddress)方法上抛出一个错误: 我被告知: 无法将

我正在尝试向REST WCF服务(Windows Server 2008)添加IoC支持。我不熟悉这一点,并遵循以下视频中提供的说明:

该视频介绍了一些类,这些类帮助我在公开WCF端点的同时启动并运行StructureMap的IoC。我已经在这篇文章的末尾发布了所有代码

当我运行代码时,自定义类StructureMapServiceHost在StructureMapServiceHost(类型serviceType,参数Uri[]baseAddress)方法上抛出一个错误:

我被告知:

无法将提供的服务类型作为服务加载,因为它没有默认(无参数)构造函数。要解决此问题,请向该类型添加默认构造函数,或将该类型的实例传递给主机。

这是真的,事实并非如此。但视频示例也没有。以下是我的服务:

[ServiceBehavior(InstanceContextMode=InstanceContextMode.Single)]
    public class UserService : IUserService
    {
        public UserService(IUserRepository specification)
        {
            Specification = specification;
        }

        public List<User> GetAllUsers()
        {
            return Specification.GetAllUsers();
        }

        public User GetUser(string userId)
        {
            return Specification.GetUserById(new Guid(userId));
        }

        private List<User> SearchForUsers(string searchString)
        {
            return Specification.SearchUsers(searchString);
        }

        public IUserRepository Specification { get; set; }

    }



public class IoCServiceBehavior : IServiceBehavior
    {
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {   
        }

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

        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers)
            {
                new StructureMapInstanceProvider(serviceDescription.ServiceType);
            }
        }
    }


public class StructureMapInstanceProvider : IInstanceProvider
{
    private readonly Type _serviceType;

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

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

    public object GetInstance(InstanceContext instanceContext, Message message)
    {
        var instance = ObjectFactory.GetInstance(_serviceType);

        return instance;
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        throw new NotImplementedException();
    }
}




public class StructureMapServiceHostFactory : ServiceHostFactory
    {
        public StructureMapServiceHostFactory()
        {
            IoCBootstrap.SetupIoc();
        }

        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            return new StructureMapServiceHost(serviceType, baseAddresses);
        }
    }
并补充说:

public StructureMapServiceHost(Object singletonInstance, params Uri[] baseAddress)
            : base( singletonInstance, baseAddress) { }
然后从我的UserService构造函数中删除该参数。我没有得到错误:

HTML文档不包含Web文档 服务发现信息


我现在无法查看视频(互联网限制),但我非常确定他们示例中的类根本没有任何构造函数。在这种情况下,编译器会代表您生成一个空的无参数构造函数。因此,他们的类毕竟有一个默认构造函数

至于异常,这似乎非常简单:您的无参数构造函数不会初始化
规范
属性,因此它总是
null
——一旦您尝试在方法中访问它,这自然会导致
NullReferenceException

您在这里的目的似乎是自己创建
UserService
对象,并将
IUserRepository
传递给它,不是吗?(或者,或许可以使用你的国际奥委会框架来实现这一点?)


在这种情况下,最好使用
ServiceHost
构造函数的重载,该构造函数接受
对象,而不是
类型
。这样,您就可以完全控制
UserService
对象,并且根本不需要默认构造函数。

您的服务使用InstanceContextMode.SingleCall和WCF团队以其无限的智慧决定,当InstanceContextMode为SingleCall时,不会调用IInstanceProvider来创建实例(请参阅接口定义标题下的第二段)

目前,我在服务主机工厂有一种不太理想的解决方法:

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using StructureMap;
using StructureMap.Pipeline;
using System.Linq;

using ServiceHostCreator = System.Func<System.Type, System.Uri[], System.ServiceModel.ServiceHost>;

namespace x.ServiceExtensions
{
    public class xWebServiceHostFactory : ServiceHostFactory
    {
        private readonly IDictionary<InstanceContextMode, ServiceHostCreator> _serviceHostCreators;

        public xWebServiceHostFactory()
        {
            ObjectFactory.Initialize( init =>
                                      init.Scan( scan =>
                                                     {
                                                         scan.AssembliesFromApplicationBaseDirectory();
                                                         scan.IgnoreStructureMapAttributes();
                                                         scan.LookForRegistries();
                                                     } ) );
            _serviceHostCreators = new Dictionary<InstanceContextMode, ServiceHostCreator>
                                        {
                                            { InstanceContextMode.PerCall, ( t, a ) => PerCallServiceHostCreator( t, a ) },
                                            { InstanceContextMode.PerSession, ( t, a ) => PerSessionServiceHostCreator( t, a ) },
                                            { InstanceContextMode.Single, ( t, a ) => SingleInstanceServiceHostCreator( t, a ) }
                                        };
        }

        protected override ServiceHost CreateServiceHost( Type serviceType, Uri[] baseAddresses )
        {
            var serviceInstanceContextMode = GetServiceInstanceContextMode( serviceType );
            var serviceHostCreator = _serviceHostCreators[ serviceInstanceContextMode ];
            return serviceHostCreator( serviceType, baseAddresses );
        }

        private static InstanceContextMode GetServiceInstanceContextMode( Type serviceType )
        {
            var serviceBehaviour = serviceType
                .GetCustomAttributes( typeof ( ServiceBehaviorAttribute ), true )
                .Cast<ServiceBehaviorAttribute>()
                .SingleOrDefault();
            return serviceBehaviour.InstanceContextMode;
        }

        private static ServiceHost PerCallServiceHostCreator( Type serviceType, Uri[] baseAddresses )
        {
            var args = new ExplicitArguments();
            args.Set( serviceType );
            args.Set( baseAddresses );
            var serviceHost = ObjectFactory.GetInstance<TelaWebServiceHost>( args );
            return serviceHost;
        }

        private static ServiceHost PerSessionServiceHostCreator( Type serviceType, Uri[] baseAddresses )
        {
            return PerCallServiceHostCreator( serviceType, baseAddresses );
        }

        private static ServiceHost SingleInstanceServiceHostCreator( Type serviceType, Uri[] baseAddresses )
        {
            var service = ObjectFactory.GetInstance( serviceType );
            var args = new ExplicitArguments();
            args.Set( typeof(object), service );
            args.Set( baseAddresses );
            var serviceHost = ObjectFactory.GetInstance<TelaWebServiceHost>( args );
            return serviceHost;
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.ServiceModel;
使用System.ServiceModel.Activation;
使用结构图;
使用StructureMap.Pipeline;
使用System.Linq;
使用ServiceHostCreator=System.Func;
名称空间x.ServiceExtensions
{
公共类xWebServiceHostFactory:ServiceHostFactory
{
私有只读IDictionary _serviceHostCreators;
公共xWebServiceHostFactory()
{
ObjectFactory.Initialize(init=>
初始化扫描(扫描=>
{
scan.AssembliesFromApplicationBaseDirectory();
scan.IgnorStructureMappAttributes();
scan.LookForRegistries();
} ) );
_serviceHostCreators=新字典
{
{InstanceContextMode.PerCall,(t,a)=>PerCallServiceHostCreator(t,a)},
{InstanceContextMode.PerSession,(t,a)=>PerSessionServiceHostCreator(t,a)},
{InstanceContextMode.Single,(t,a)=>SingleInstanceServiceHostCreator(t,a)}
};
}
受保护的重写ServiceHost CreateServiceHost(类型serviceType,Uri[]baseAddresses)
{
var serviceInstanceContextMode=GetServiceInstanceContextMode(serviceType);
var serviceHostCreator=_serviceHostCreators[serviceInstanceContextMode];
返回serviceHostCreator(serviceType,baseAddresses);
}
私有静态InstanceContextMode GetServiceInstanceContextMode(类型serviceType)
{
var servicephavior=serviceType
.GetCustomAttributes(typeof(ServiceBehaviorAttribute),true)
.Cast()
.SingleOrDefault();
返回ServiceBehavior.InstanceContextMode;
}
专用静态ServiceHost PerCallServiceHostCreator(类型serviceType,Uri[]基本地址)
{
var args=新的明确目标();
参数集(服务类型);
参数集(基地址);
var serviceHost=ObjectFactory.GetInstance(args);
返回服务主机;
}
专用静态ServiceHost PerSessionServiceHostCreator(类型serviceType,Uri[]基本地址)
{
返回PerCallServiceHostCreator(服务类型、基本地址);
}
专用静态ServiceHost SingleInstanceServiceHostCreator(类型serviceType,Uri[]基本地址)
{
var service=ObjectFactory.GetInstance(serviceType);
var args=新的明确目标();
参数集(类型(对象)、服务);
参数集(基地址);
var serviceHost=ObjectFactory.GetInstance(args);
返回服务主机;
}
}
}

这是一项正在进行的工作,可能有更好的方法,但目前我找不到。

对于任何试图做类似工作的人
public StructureMapServiceHost(Object singletonInstance, params Uri[] baseAddress)
            : base( singletonInstance, baseAddress) { }
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using StructureMap;
using StructureMap.Pipeline;
using System.Linq;

using ServiceHostCreator = System.Func<System.Type, System.Uri[], System.ServiceModel.ServiceHost>;

namespace x.ServiceExtensions
{
    public class xWebServiceHostFactory : ServiceHostFactory
    {
        private readonly IDictionary<InstanceContextMode, ServiceHostCreator> _serviceHostCreators;

        public xWebServiceHostFactory()
        {
            ObjectFactory.Initialize( init =>
                                      init.Scan( scan =>
                                                     {
                                                         scan.AssembliesFromApplicationBaseDirectory();
                                                         scan.IgnoreStructureMapAttributes();
                                                         scan.LookForRegistries();
                                                     } ) );
            _serviceHostCreators = new Dictionary<InstanceContextMode, ServiceHostCreator>
                                        {
                                            { InstanceContextMode.PerCall, ( t, a ) => PerCallServiceHostCreator( t, a ) },
                                            { InstanceContextMode.PerSession, ( t, a ) => PerSessionServiceHostCreator( t, a ) },
                                            { InstanceContextMode.Single, ( t, a ) => SingleInstanceServiceHostCreator( t, a ) }
                                        };
        }

        protected override ServiceHost CreateServiceHost( Type serviceType, Uri[] baseAddresses )
        {
            var serviceInstanceContextMode = GetServiceInstanceContextMode( serviceType );
            var serviceHostCreator = _serviceHostCreators[ serviceInstanceContextMode ];
            return serviceHostCreator( serviceType, baseAddresses );
        }

        private static InstanceContextMode GetServiceInstanceContextMode( Type serviceType )
        {
            var serviceBehaviour = serviceType
                .GetCustomAttributes( typeof ( ServiceBehaviorAttribute ), true )
                .Cast<ServiceBehaviorAttribute>()
                .SingleOrDefault();
            return serviceBehaviour.InstanceContextMode;
        }

        private static ServiceHost PerCallServiceHostCreator( Type serviceType, Uri[] baseAddresses )
        {
            var args = new ExplicitArguments();
            args.Set( serviceType );
            args.Set( baseAddresses );
            var serviceHost = ObjectFactory.GetInstance<TelaWebServiceHost>( args );
            return serviceHost;
        }

        private static ServiceHost PerSessionServiceHostCreator( Type serviceType, Uri[] baseAddresses )
        {
            return PerCallServiceHostCreator( serviceType, baseAddresses );
        }

        private static ServiceHost SingleInstanceServiceHostCreator( Type serviceType, Uri[] baseAddresses )
        {
            var service = ObjectFactory.GetInstance( serviceType );
            var args = new ExplicitArguments();
            args.Set( typeof(object), service );
            args.Set( baseAddresses );
            var serviceHost = ObjectFactory.GetInstance<TelaWebServiceHost>( args );
            return serviceHost;
        }
    }
}