gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 22:09:55 25 4
gpt4 key购买 nike

我正在尝试将 IoC 支持添加到我的 REST WCF 服务 (Windows Server 2008)。我是新手,正在按照以下视频中提供的说明进行操作:

http://www.dimecasts.net/Content/WatchEpisode/150

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

当我运行我的代码时,自定义类 StructureMapServiceHost 在 StructureMapServiceHost(Type serviceType, params Uri[] baseAddress ) 方法中抛出错误:

   public class StructureMapServiceHost : ServiceHost
{
public StructureMapServiceHost() {}

public StructureMapServiceHost(Type serviceType, params Uri[] baseAddress)
: base(serviceType, baseAddress)
{

}

protected override void OnOpening()
{
Description.Behaviors.Add( new IoCServiceBehavior());
base.OnOpening();
}
}

有人告诉我:

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

这是真的,它不是。但是视频示例也没有。以下是我的服务:

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

有什么想法吗?谢谢。

编辑 ************ *************** *****

从我删除的 StructureMapServiceHost 中:

public StructureMapServiceHost(Type serviceType, params Uri[] baseAddress)
: base(serviceType, baseAddress) { }

并添加:

public StructureMapServiceHost(Object singletonInstance, params Uri[] baseAddress)
: base( singletonInstance, baseAddress) { }

然后从我的 UserService 构造函数中删除了参数。我没有收到错误消息:

The HTML document does not contain Web service discovery information.

最佳答案

您的服务使用 InstanceContextMode.SingleCall 并且 WCF 团队以他们无限的智慧决定,当 InstanceContextMode 为 SingleCall 时,不调用 IInstanceProvider 来创建实例(参见 https://learn.microsoft.com/en-us/archive/blogs/carlosfigueira/wcf-extensibility-iinstanceprovider - 接口(interface)声明标题下方的第二段)。

目前我在服务主机工厂中有一个不太理想的方法来解决这个问题:

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

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

关于c# - 尝试向我的 WCF 服务添加 IoC 支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4736633/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com