Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC Dependency Injection Unity with WCF services - working sample solution

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.

like image 896
Elim99 Avatar asked Dec 05 '22 20:12

Elim99


1 Answers

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.

like image 130
Darin Dimitrov Avatar answered Dec 29 '22 10:12

Darin Dimitrov