How to insert controller for MVC4 / VS2012 / Web API

I read or tried to read too many "how to do it" and they got exactly nowhere. Unity? System.Web.Http.Dependencies? Ninject? StructureMap? Ugh. I just want something simple to work! I just can't figure out what this state is. There are completely different approaches and the examples seem incomplete. Heck, the best lead had a sample project with it ... that I can't load in VS2010 or 2012. ARG! I wasted 3/4 of the day on what I thought should have been half an hour longer and move on! It's just plumbing!

I have a generics based repository to handle many datasets that support the same operations.

IRepository

I want to control which repository each dataset is bound to. This will allow me to link everything to the test XML repository, pushing them into the SQL repository as the project progresses.

I would appreciate some help with this! Thank!

+3


source to share


1 answer


It looks like you are in the state I was in a couple of years ago.

Please note that if you need further help, I am sending you the code. It's just hard to enter all the code here.

I will try to explain the existing architecture in a project I am working on. This post is a bit long, but I'm trying to give you an overall picture of how using an IOC can help you in many ways.

Therefore I am using Ninject. After trying Castle Windsor for a while, I found that Ninject gets up and running easily. Ninject has a cool website to get you started.

First of all my project structure looks like this: (top to bottom and this is MVC)

View - Razor ViewModel - I am using 1 ViewModel for the View

ViewModelBuilder . Creates my viewmodels for my views (used to abstract code from my controller, so my controller stays neat and tidy)

AutoMapper - for mapping domain objects to view models

Controller - calls my service layer to get domain objects

Domain Entities - My Domain Views

ServiceLayer (business layer) . Calls my repository level to get entities or domain collections of these

AutoMapper again - for mapping custom types from 3rd party providers in my domains

RepositoryLayer - Performs CRUD operations on my datastores

It's a hierarchy, but domain entities are similar and are used in several different layers.

Note: some additional tools mentioned in this post are as follows:

AutoMapper - maps objects to other objects - eliminates the need to write loads of mapping code

Moq . Allows you to fake unit testing material. This is mentioned later.

Now about Ninject.

Each layer is marked with an interface. This must be done so that Ninject can speak for himself.

When I find the IVehicleRepository inject it with the real VehicleRepository, or even inject it with FakeVehicleRepository if I need a fake.

(this refers to your comment - "This will allow me to link everything to a test XML store")

Each layer now has a counter constructor so that Ninject (or any other IOC container) can insert whatever it needs:



public VehicleManager(IVehicleRepository vehicleRepository)
{
    this._vehicleRepository = vehicleRepository;
}

      

The VehicleManager is in my Service Layer (not to be confused with anything related to web services). The service layer is what we would call the business layer. It looks like a lot of people use a phrase. (although I think this is annoying since it makes me think about web services or WCF and not just the business layer ... anyway ...)

now without going into the tiny size of Ninject, set the following line of code in my NinjectWebCommon.cs that says what to do:

kernel.Bind<IVehicleRepository>().To<VehicleRepository>().InRequestScope();

      

It says:

Hey Nindek, when I ask for this, I ask for a specific VehicleRepository implementation.

As mentioned earlier, I could replace VehicleRepository with FakeVehicleRepository so I didn't have to read from the real database.

So, as you can now imagine, each layer only depends on the interfaces.

I don't know how many units of testing you did, but you can also imagine that if you wanted to unit test your service level, and it had specific references to your repository level, you could not unit test as you would be ACTIVE hitting your repository and hence reading from the real database.

Remember unit testing is called unit testing because it only tests one thing. Hence the word UNIT. Since everything only knows about interfaces, this means that you can test the method at the service level and poke fun at the repository.

So, if your service layer has a method like this:

public bool ThisIsACar(int id)
{
   bool isCar = false;
   var vehicle = vehicleRepository.GetVehicleById(id);

   if(vehicle.Type == VehicleType.Car)
   {
       isCar = true;
   }
   else
   {
       isCar = false;
   }
}

      

You would not want the vehicle call to be called so you can do Moq what VehicleRepository returns. Basically you can only use Mock if it implements the interface.

So your unit test would look like this (some pseudo code here):
        [TestMethod]
        public void ServiceMethodThisIsACar_Returns_True_When_VehicleIsACar()
        {
            // Arrange
            _mockRepository.Setup(x => x.ThisIsACar(It.IsAny<int>)).returns(new Car with a type of VehicleType.Car)

            // Act
            var vehicleManager = new VehicleManager(_mockVehicleRepository.Object);
            var vehicle = vehicleManager.ThisIsACar(3);

            // Assert
            Assert.IsTrue(vehicle.VehicleType == VehicleType.Car)
        }

      

So, as you can see, at this point and this is very simplistic, you want to test the IF statement in your service layer to make sure the result is correct.

You would check your repository in your unit tests and perhaps mock the object frame to work if you are using it.

So, in general, I would say, use what ever the IOC container gets you up and running fastest with the least amount of pain.

I would also say try and unit test whatever you can. This is great for several reasons. Obviously, it checks the code you wrote, but it will also show you right away if you did something stupid, like re-creating a specific repository. You will quickly see that you will not have an interface to mock your unit tests, and this will lead you to backtracking and refactoring your code.

I found that with the IOC it takes a while to just get it. It confuses you until he clicks. After that, it will be easy for you to wonder how you lived without him.

Here's a list of things I can't live without Automapper Moq Free Checkout Resharper - some hate it, I love it, mainly for unit testing it.

It takes too long anyway. Let me know what you think.

thanks RuSs

+3


source







All Articles