Easily implement dependency injection for the constructor of the WCF Service

Source: Internet
Author: User

Today, when developing a blog program's WCF Service, I want to use constructor in the "WCF Service implementation" to perform dependency injection. The Code is as follows:

    public class BlogService : IBlogService
{
private IBlogSiteService _blogSiteService;

public BlogService(IBlogSiteService blogSiteService)
{
_blogSiteService = blogSiteService;
}
}

The dependency injection container uses unity. The implementation of iblogsiteservice has been injected through bootstrapper when the WCF host runs. For more information, see the beauty of loneliness: separating application_start makes the initialization code more elegant.

However, when the client calls this WCF Service, an exception occurs:

The service type provided cocould not be loaded as a service because it does not have a default (parameter-less) constructor.
To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.

This exception is a normal phenomenon. I didn't tell the WCF host how it knows that I am going to perform dependency injection, and there is no idea between us. The default constructor is used to create a WCF Service instance. Therefore, an exception is thrown.

So how can we solve this problem?

Microsoft has long considered this and provided the iinstanceprovider and iservicebehavior interfaces. We only need to implement these two interfaces, and make the class implementing iservicebehavior become an attribute (inherited from attribute), and then add it to the WCF Service implementation class, you can implement dependency injection for the WCF constructor.

The specific implementation steps are as follows:

1. Implement the iinstanceprovider interface-iocinstanceprovider

1. Create a class iocinstanceprovider to implement the iinstanceprovider interface.

2. implement the three methods of the iinstanceprovider interface and introduce your own IOC container (for example, we use cnblogs. infrastructure. crosscutting. IOC), that is, let WCF get the WCF Service instance through your IOC container. The sample code is as follows:

public class IocInstanceProvider : IInstanceProvider
{
Type _serviceType;
IContainer _container;

public IocInstanceProvider(Type serviceType)
{
_serviceType = serviceType;
_container = CNBlogs.Infrastructure.CrossCutting.IoC.
IoCFactory.Instance.CurrentContainter;
}

#region IInstanceProvider Members

public object GetInstance(InstanceContext instanceContext, Message message)
{
return _container.Resolve(_serviceType);
}

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

public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
if (instance is IDisposable)
((IDisposable)instance).Dispose();
}

#endregion
}

Note: Your IOC container needs to inject the corresponding WCF Service instance in advance. For example, our injection:

container.RegisterType<IBlogService, BlogService>();

Iblogservice is a WCF Service Interface and blogservice is a WCF Service implementation.

Ii. Implement the iservicebehavior interface-iocservicebehavior

1. Create a class iocservicebehavior, inherit from attribute, and implement iservicebehavior

public class IocServiceBehavior : Attribute, IServiceBehavior

2. Implement the addbindingparameters () method of iservicebehavior and introduce the previously created iocinstanceprovider

public class IocServiceBehavior : Attribute, IServiceBehavior
{
#region IServiceBehavior Members

public void AddBindingParameters(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase,
Collection<ServiceEndpoint> endpoints,
BindingParameterCollection bindingParameters)
{
foreach (var item in serviceHostBase.ChannelDispatchers)
{
var dispatcher = item as ChannelDispatcher;
if (dispatcher != null)
{
dispatcher.Endpoints.ToList().ForEach(endpoint =>
{
endpoint.DispatchRuntime.InstanceProvider = new
IocInstanceProvider(serviceDescription.ServiceType);
});
}
}
}

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

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

#endregion
}

3. Add the [iocservicebehavior] attribute to the WCF Service implementation class.

The Code is as follows:

[IocServiceBehavior]
public class BlogService : IBlogService
{
private IBlogSiteService _blogSiteService;

public BlogService(IBlogSiteService blogSiteService)
{
_blogSiteService = blogSiteService;
}

#region IBlogService Members

public BlogSiteDto GetBlogSiteWithPosts(int blogId,
bool withPostBody, int itemcount)
{
return _blogSiteService.GetWithPosts(blogId,
withPostBody, itemcount);
}

#endregion
}

Done! Is it easy!

For the above implementation code, refer to the self domain oriented N-layered. Net 4.0 sample app (http://microsoftnlayerapp.codeplex.com/). If you are interested in DDD, it is recommended to read the code of this project.

Code Improvement

Based on the suggestions of artech and the reference of WCF extensibility-iinstanceprovider, improve the iocservicebehavior code to implement the applydispatchbehavior interface. The Code is as follows:

public class IocServiceBehavior : Attribute, IServiceBehavior
{
#region IServiceBehavior Members

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

public void ApplyDispatchBehavior(ServiceDescription serviceDescription,
ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
if (!ed.IsSystemEndpoint)
{
ed.DispatchRuntime.InstanceProvider =
new IocInstanceProvider(serviceDescription.ServiceType);
}
}
}
}

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

#endregion
}

Summary

Are you using IOC? If no, you are out. Not only ASP. net can be easily IOC (easy to get along with: When ASP. net MVC falls in love with IOC), and unit tests can also be IOC (dream to be a reality: Use xunit.net to implement constructor dependency injection in unit tests ).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.