Doug Chamberlain
Doug Chamberlain

Reputation: 11351

How can I decouple dependecies in my controller?

I want to be able to write test code. But my Action is coupled to my DataContext. How can I remove dependency?

    public ViewResult About()
    {
        var db = new CamaDataContext();

        var item = new PropertyViewModel();


        AutoMapper.Mapper.Map(db.dataProperty.FirstOrDefault(),item);

        return View(item);
    }

Upvotes: 0

Views: 164

Answers (5)

cwharris
cwharris

Reputation: 18125

Microsoft has a great tutorial in this. It's not perfectly straight forward, but a good study of the classes and trying to put it in to practice will help you understand it just fine.

Its specific for Entity Framework, but the principles still apply for non-EF work.

http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

Upvotes: 1

Adam Tuliper
Adam Tuliper

Reputation: 30152

You can refactor the above code easily to test it (assuming you have some business logic to test). Any logic is moved out to a class that you pass in the X entity to. Then you simply test your logic by populating the classes and sending it in.

As an alternative, keep your controller action extremely lightweight so it may not require testing.

Also on a separate note, dispose of your context class:

using(var db = new CamaDataContext()) { .. return View(..) }

Also consider the [AutoMap()] attribute as shown here to keep your action method even thinner.

http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/

I would content a two line method in a controller as such wouldn't require testing.

Upvotes: 1

Anthony Shaw
Anthony Shaw

Reputation: 8166

Use a dependency injection framework such as ninject or structuremap to pass it in through the controller's constructor, then when you're writing your tests you can pass those dependencies in thought constructor.

This would also provide you the opportunity to mock those depenedencies out and not actually have to make calls to your database while testing

Upvotes: 1

Justin Niessner
Justin Niessner

Reputation: 245449

  1. Create Repository Interfaces for the different Entities.

  2. Create Concrete Repositories for different Entities.

  3. Store those repositories at the Controller level.

  4. Use the constructors for your Controller to allow the Repositories to be Injected (and to use the Concrete implementations if none are supplied).

This will allow you to Mock the Repositories during Unit Testing so that the two aren't tightly coupled.

Upvotes: 2

Chris Shain
Chris Shain

Reputation: 51359

You could look into an IoC container, like Castle Windsor, SpringFramework.net, or StructureMap. This is the core of what they are designed to do.

Upvotes: 0

Related Questions