我正在IIS上托管WCF应用程序。 我正在自定义ServiceHostFactory初始化一个IoC容器。
基本上我想要的是能够将IoC容器“注入”到在该ServiceHost范围内创建的每个Service实例。
你将如何实现这一目标?
爱丽儿
答案 0 :(得分:2)
就像你说的那样,你需要一个自定义的ServiceHostFactory,用于创建你的服务。像这样:
public class SessionPerCallServiceHostFactory : ServiceHostFactory { public SessionPerCallServiceHostFactory() { } protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { return new SessionPerCallServiceHost(serviceType, baseAddresses); } }
您还需要一个负责创建必要服务的ServiceHost:
public class SessionPerCallServiceHost : ServiceHost { public SessionPerCallServiceHost() { } public SessionPerCallServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { } protected override void OnOpening() { Description.Behaviors.Add(new SessionPerCallServiceBehavior()); base.OnOpening(); } }
使用IServiceBehavior的自定义实现,它将能够提供用于创建服务实例的InstanceProvider:
public class SessionPerCallServiceBehavior : IServiceBehavior { public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (ChannelDispatcherBase cdb in serviceHostBase.ChannelDispatchers) { ChannelDispatcher cd = cdb as ChannelDispatcher; if (cd != null) { foreach (EndpointDispatcher ed in cd.Endpoints) { ed.DispatchRuntime.InstanceProvider = new SessionPerCallInstanceProvider(serviceDescription.ServiceType); } } } } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection bindingParameters) { } public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } }
最后,实例提供程序允许您使用IoC在请求的服务实例中注入您想要的任何内容:
public class SessionPerCallInstanceProvider : IInstanceProvider { private readonly Type _serviceType; public SessionPerCallInstanceProvider(Type serviceType) { _serviceType = serviceType; } public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message) { //I'm creating it without any tricks but you could use your IoC container here return Activator.CreateInstance(_serviceType); } public object GetInstance(InstanceContext instanceContext) { return GetInstance(instanceContext, null); } public void ReleaseInstance(System.ServiceModel.InstanceContext instanceContext, object instance) { } }
希望它有所帮助!