将 Unity 依赖注入与 WCF 服务结合使用
对其他问题进行一些研究后,我得到以下结果:
MyServiceHost:
public class MyServiceHost : ServiceHost
{
public MyServiceHost(IUnityContainer container, Type serviceType, params Uri[] baseAddresses)
: base(serviceType, baseAddresses)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
foreach (var cd in this.ImplementedContracts.Values)
{
cd.Behaviors.Add(new DependencyInjectionInstanceProvider(container));
}
}
}
DependencyInjectionInstanceProvider:
public class DependencyInjectionInstanceProvider : IInstanceProvider, IContractBehavior
{
private readonly IUnityContainer container;
public DependencyInjectionInstanceProvider(IUnityContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}
#region IInstanceProvider Members
public object GetInstance(InstanceContext instanceContext, Message message)
{
return this.GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
var serviceType = instanceContext.Host.Description.ServiceType;
return this.container.Resolve(serviceType);
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
this.container.Teardown(instance);
}
#endregion
#region IContractBehavior Members
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
dispatchRuntime.InstanceProvider = this;
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
}
#endregion
}
MyServiceHostFactory:
public class MyServiceHostFactory : ServiceHostFactory
{
private readonly IUnityContainer container;
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new MyServiceHost(this.container, serviceType, baseAddresses);
}
}
尝试构造函数注入的电子邮件服务:
public class EmailValidator : IEmailValidator
{
private IFakeDAL fakeDAL;
public EmailValidator(IFakeDAL fakeDAL)
{
this.fakeDAL = fakeDAL;
}
public bool ValidateAddress(string emailAddress)
{
Console.WriteLine("Validating: {0}", emailAddress);
string pattern = @"^([0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*@(([0-9a-zA-Z])+([-\w]*[0-9a-zA-Z])*\.)+[a-zA-Z]{2,9})$";
return Regex.IsMatch(emailAddress, pattern);
}
}
我的控制台主机启动服务:
static void Main(string[] args)
{
Type serviceType = typeof(EmailValidator);
Uri serviceUri = new Uri("http://localhost:8080/");
MyServiceHostFactory shf = new MyServiceHostFactory();
ServiceHost host = shf.CreateServiceHost(serviceType, serviceUri);
//ServiceHost host = new ServiceHost(serviceType, serviceUri);
host.Open();
我的问题出在控制台主机逻辑上。 CreateServiceHost 调用存在语法错误,因为第一个参数需要构造函数字符串而不是类型。我不明白,因为它确实接受类型参数。除此之外,我不明白应该在哪里将 IFakeDAL 映射到具体的类。我可以在 app.config 文件中执行此操作还是应该在其他地方注册?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
ServiceHostFactory
用于在 IIS 中托管。在自托管中,您应该直接使用派生的ServiceHost
。 此处 您有完整的示例,包括 Unity 配置。ServiceHostFactory
is for hosting in IIS. In self hosting you should use your derivedServiceHost
directly. Here you have whole example including Unity configuration.我在 Windows 服务中使用以下类来创建 WCF 服务并使用 unity 向其注入依赖项。
UnityInstanceProvider:
UnityServiceBehavior:
UnityServiceHost:
使用这些类,您可以执行以下操作(服务的配置在 .config 中完成):
I´m using the following classes in my windows service to create WCF services and inject dependencies to it using unity.
UnityInstanceProvider:
UnityServiceBehavior:
UnityServiceHost:
With this classes you can do the following (The configuration of services is done in .config):
CreateServiceHost 方法需要一个
Uri
数组实例,所以尝试这样做:您可以将接口映射到 XML 或代码中的类型,但我建议使用代码,因为 XML 的维护开销太高。
Main
方法是一个优秀的组合根 ,但如果您想在该级别配置容器,则需要将其从Main
方法传递到MyServiceHostFactory
- 当您托管服务时,这完全没问题在控制台应用程序,但如果您想将其托管在 IIS 中,则无法工作,其中MyServiceHostFactory
应该是组合根,因为 IIS 需要默认构造函数。The CreateServiceHost method expects an array of
Uri
instances, so try this instead:You can map interfaces to types in either XML or code, but I'd recommend code, since XML has too high a maintenance overhead.
The
Main
method is an excellent Composition Root, but if you want to configure the container at that level, you'll need to pass it from theMain
method toMyServiceHostFactory
- which is perfectly fine when you host the service in a console application, but will not work if you want to host it in IIS, whereMyServiceHostFactory
should be the Composition Root, since IIS requires a default constructor.