4

I'm looking for a working sample of an ASP.NET MVC web application that uses Unity and calls an WCF service. I've looked at a lot of explanations on how to add dependency injection to WCF services but frankly I'm a little over my head here. It doesn't help that I'm new to WCF services as well.

I'm currently using Unity with Contructor injection for our ASP.NET MVC applications but so far we aren't using any WCF Web Services. The plan is to start using web services and I'm very confused on how to incorporate Unity with them.

I would love a nice working sample that I could walk through to better understand how to go about it.

1
  • 1
    FWIW, my book has a lot of sample code associated with it. It doesn't have an ASP.NET MVC application that invokes a WCF service, but it does have examples of DI in both ASP.NET MVC, and a WPF application which consumes a WCF service using DI. affiliate.manning.com/idevaffiliate.php?id=1150_236 Commented Aug 31, 2011 at 21:48

3 Answers 3

12

I will try to provide you with some guidance.

Let's suppose that you have an existing products WCF service that is defined like this (we don't care about the implementation, that's not important for the moment, you could implement it as you wish, varying from hardcoded values, passing through a SQL database and an ORM, to consuming another service on the cloud):

[DataContract]
public class Product
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string Name { get; set; }
}

[ServiceContract]
public interface IProductsService
{
    [OperationContract]
    Product Get(int id);
}

Now in your ASP.NET MVC application the first step is to add a service reference to it by pointing to the WSDL. This will generate proxy client classes.

Next you could add the Unity.Mvc3 NuGet package to your MVC application

Then in your Application_Start you could configure the container (obviously this configuration could be externalized into a separate method to avoid cluttering your Global.asax with it):

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    var container = new UnityContainer();
    container
        .RegisterType<IProductsService, ProductsServiceClient>()
        .Configure<InjectedMembers>()
        .ConfigureInjectionFor<ProductsServiceClient>(new InjectionConstructor("*"));
    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

IProductsService and ProducsServiceClient used in this configuration are the proxy classes generated when you imported the web service definition.

From now on things become trivial:

public class HomeController : Controller
{
    private readonly IProductsService _productsService;
    public HomeController(IProductsService productsService)
    {
        _productsService = productsService;
    }

    public ActionResult Index()
    {
        var product = _productsService.Get(1);
        return View(product);
    }
}

and some corresponding Index view:

@model Product
<div>
    @Html.DisplayFor(x => x.Name)
</div>

As you can see from this example thanks to the IProductsService abstraction, HomeController is totally decoupled from any concrete implementations of the service. In Today in your Global.asax you decided to use WCF (ProductsServiceClient), but tomorrow you could decide to use some completely different implementation. With a single changes in your DI container configuration you could switch the implementation. Thanks to this weak coupling, your controllers are fully unit testable in isolation.

What is important to realize here is that your business is the Product class and the IProductsService interface. This is what reflects your domain. This is the M in MVC. Implementations could change, but this should stay the same, otherwise you have wrongly identified your business requirements which could be catastrophic in long term.

Remark: one thing that I haven't covered in this example, and which is very important, is the usage of view models. In a properly architected ASP.NET MVC application you should never pass domain models to your views (in this example the Product class). You should use view models. View models are classes that are specifically designed for the requirements of a given view. So in a real world ASP.NET MVC application you would have a ProductViewModel class which to which the Product domain model will be mapped in the controller action and it is this ProductViewModel that will be passed to the view. Those view models should be defined in the MVC project as, contrary to your domain models, they are not reusable and reflect only the specific requirements of a single view. To ease the mapping between your domain models and view models you may take a look at AutoMapper.

Sign up to request clarification or add additional context in comments.

3 Comments

Excellent article, and a great explanation.. this has cleared lots of questions of mine regarding DI.. However, I still think, that instead of adding service reference in your MVC project, you can just define endpoint in your web.config, and can create a running instance in Global.asax.. Do you know how can we implement this? or you reckon its not the right approach?
If you don't want to use the Add Service reference wizard in VS you could directly use the svcutil.exe tool which is part of the VS SDK to generate strongly typed proxies from an existing WCF service. As far as your question about configuring an endpoint in web.config and creating a running instance in Global.asax I don't really understand what you mean.
using this way, do i need to add service reference in web project ?
4

It sounds like you're already injecting your MVC Controllers using Unity and all you want to do is start injecting the WCF services you host as well. To inject WCF services, you need to use an IInstanceProvider.

Complete working solution is here:

http://orand.blogspot.com/2006/10/wcf-service-dependency-injection.html

You need 4 very very simple classes:

MyServiceHostFactory 
MyServiceHost 
DependencyInjectionServiceBehavior
DependencyInjectionInstanceProvider 

define those, specify your new ServiceHostFactory:

<%@ ServiceHost
Service="NamespaceC.ServiceLayer, AssemblyC"
Factory="NamespaceD.MyServiceHostFactory, AssemblyD"
%>

and you're done.

1 Comment

Do you know of an example that uses Unity versus Spring.NET? It would also be nice to have a downloadable zip file as well.
0

I know it's a bit late in the game, but I've written a Nuget package to simplify the process of using WCF in your MVC/WebApi app, and it leverages Unity.

Check out Unity.Mvc.Wcf on Codeplex or GitHub for details.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.