Where to instantiate Data Context (adapter, connection, session, etc) in MVC? - asp.net-mvc

We are building an ASP.NET MVC site, and I'm struggling with where to define a connection to best enable unit testing (I use 'connection' generically - it could be a session, a connection, an adapter, or any other type of data context that can manage transactions and database operations).
Let's say we have 3 classes:
UserController
UserService
UserRepository
In the past, we'd do something like this within a method of the UserService:
Using (ISomeSession session = new SomeSession())
{
session.StartTransaction();
IUserRepository rep = new UserRepository(session);
rep.DoSomething();
rep.Save();
session.Commit();
}
However, it wasn't really possible to unit test this since the dependency on SomeSession wasn't injected. However, if we use D.I. to inject the dependency in the UserService, the session hangs around for the life of the UserService. If there are multiple services called from the UserController, each could have sessions just hanging around until the UserController is garbage collected.
Any thoughts on how to better manage this? Am I missing something obvious?
Edit
Sorry if I wasn't clear - I understand that I can use Dependency Injection with the Session/Data Context, but then it's being maintained over the life of the Service class. For any longer-running actions/methods (i.e. let's say the service is being called by a batch process), this could lead to a lot of open sessions for no reason other than adding testability.

As RichardOD correctly observed, you can't use live database connections for writing unit tests. If you are doing it, then you are integration testing.
I have separate implementations for my repository interface, one real repository, and one fake repository for unit testing. The fake repository works on a generic list instead of a real data context. I am using DI (with Ninject to make things more comfortable, but you can do it just as well by hand) to inject the correct repository.
There are only very few instances in which I am unit testing with real connections, but that's a unit test for my repository class, not for any controller, UI or Business layer objects.
Edit: With the comment you added, I think I now understand what you were actually asking for. Funny you'd ask something about that, since I worked on the very same subject last week :-)
I instantiate the data context inside a very thin wrapper and put the context inside the HttpContext.Current.Items dictionary. This way, the context is global, but only for the current request.
Still, your question's subject is highly misleading. You were asking "where to instantiate a data context for unit testing" and the answer is that you usually don't. My unit tests still operate on fake repositories.

The easiest way is to have a Connectionstring that you define in web.config for development and production. For Unittests you define it in app.config of your Testproject.

Related

How to reinject an EF context when using contructor dependency injection with Ninject?

I am injecting all dependencies (services, context) through the contructor with the help of Ninject. The scope of all dependencies is for the current request. Everything works ok but now I want in some case to refresh/reconstruct the Entity Framework context. So basically I just want a dependency reinjected.
I could inject an UnitofWork and call some method on it to remake the context. For Entity Framework this means creating another context. But I am wondering if Ninject will be aware of this and what happens if I further need to use the context in the same request - will it use the old or new context?
To my knowledge ninject does not provide an implementation for what you specifically need.
In your case it might make sense that the client code controls the lifecycle of the ´DbContext´ explicitly. Instead of injecting the ´DbContext´ you would inject an ´IDbContextFactory´. You would need to pass the db context to everyone who will require the same instance.
I've worked on a fairly complicated SW where it was done like this.
However we've gone a step further: As a facilitation, we stored the unit of work (DataContext) in a ´ThreadLocal´. This limits your software in that you can't share the unit of work across multiple threads. However this is usually something you should not do anyway since a transaction should be as short as possible.
The benefit is that then you don't need to pass around the unit of work reference all the time, instead, you create an adapter which you can inject freely and which you use to access the current ThreadLocal's value whenever you need to access the unit of work.
You will still need to explicitly control the lifecycle of the unit of work, though. So you still need the factory which will instanciate the unit of work and assign it to the ´ThreadLocal´. At the end of the unit of work, you commit or rollback and then you reset the ´ThreadLocal´.
Also see this answer which also contains code:
How to use Ninject in a multi-threaded Windows service to get new instances of a dependency (DbContext) on every tick?
Sounds like you either need inject a DbContext factory class, or you could inject a Func< DbContext > and have Ninject resolve this as a method.

Has anyone got a good example of unit of work with multiple repositories that is not using EF?

I am about to implement the unit of work pattern with MVC3.
I have:
MVC Service Layer (BLL)
Repository Layer
Multiple types of databases
I want my service layer to get the IUnitOfWork passed to it by my IOC container. (This is easy and not part of this question).
So my service layer will do this: (Note: this is pseudo code)
(using unitOfWork)
{
ProductSqlRepository.Update();
PersonOracleRepository.Update();
IUnitOfWork.Commit();
}
All the samples I can find use EF. Whilst one of my repositories might use EF others may not.
My question is then, can I use the Unit of work pattern across multiple repositories that may sit above different types of databases (ie... EF, Oracle... other)
So, if I want to wrap an update to a SQL database and an oracle database in the ONE unit of work call, is the unit of work the way to do it.
As I mentioned, all examples I can find are for 100% EF solution, I need to mix and match.
Thanks
RuSs
The UnitOfWork scope is essentially already defined in MVC since all of your logic is done within an action. The common pattern I've seen (and what I ended up doing in my app) is to handle your unit of work via an attribute you register globally to your app and handle setting up whatever unit of work logic (transactions etc) you need to in the OnActionExecuting and OnActionExecuted of that attribute. There are a few caveats like making sure that the action isn't a child action and checking for ModelState errors but there are examples of this online. Also note that if you do not use viewmodels exclusively in your views, you may run into issues with certain frameworks lazy loading data in a view after your unit of work scope has closed.
My project used nHibernate and I used these two posts as inspiration for my implementation. Hopefully they'll give you a few ideas as well.
http://ayende.com/blog/4809/refactoring-toward-frictionless-odorless-code-what-about-transactions
http://slynetblog.blogspot.ca/2011/04/lightweight-nhibernate-and-aspnet-mvc.html

What are the next steps for unit testing with dependency injection?

I'll start out by saying I'm a huge fan of unit testing. I've been using it for a couple of years. So far, though, my use has been limited to ensuring engineering calculations are performed correctly, strings are formatted properly, etc. Basically, testing my work on class libraries to be consumed in other projects.
Now, I want to branch out and apply unit testing to my work on ASP.NET Web API. At this point I have my controller written and working with Ninject. Although I'm using Ninject, I'm still not 100% sure why I'm doing it and haven't seen the benefits yet.
On to my question, what are the next steps for unit testing my Web API controllers? What should I do next and when will I reap the benefit of using Ninject?
Next, you could create fake data (or a mock) that your controller can return to your views. This will allow you to do front end development without having to complete the back end implementation.
The benefit of using Ninject is that you can create mock objects for testing purposes. By injecting the interface instead of the concrete implementation you can easily switch between the real and mock object. To do this you simply change which one should be injected in the Ninject bindings. Using something like Rhino Mock in conjunction with Ninject you can write and test your code (controllers, views, etc) without having to fully implement all of the functionality. When you're ready to implement a mocked piece of functionality, you don't have to rewrite your code to accommodate the changes, you simply update your bindings. Now real data will display on your pages instead of the mocked data you created previously.

S#arp Architecture: How to arrange Application Services

With S#arp Architecture, my understanding is that domain logic (aka business logic) that operates on more than one type of entity is best handled by the Application Services layer.
So the classes in Application Services will need access to the Repositories. Presumably then you inject the Repositories in via the constructors. Because there is one class of repository per entity type, any fairly realistic task is going to need access to several repositories. So you might have an Application Services class looking like this:
public class DogTasks
{
public DogTasks(IRepository<Dog> dogRepository,
IRepository<Trick> trickRepository,
IRepository<DogTrick> dogTrickRepository,
IRepository<Lesson> lessonRepository)
{
// etc
}
public void TeachDogNewTrickAtALesson(int dogID, string trickName, int lessonID)
{
// etc
}
// other methods, etc
}
This Tasks class can then be injected into the relevant Controller.
So far, I think I get it. But I am perturbed by the following:
When I need a new Application Services method that uses a combination of repositories that I don't have yet, I have to choose between changing the constructor for one of my existing classes to accept the new repositories, or starting a new class altogether. Adding arguments to constructors upsets a lot of the unit tests, but proliferating new classes doesn't seem good either.
When Controllers need to do simple Repository operations (like a get) it makes sense to inject the repositories into the Controllers as well as the Application Services classes. But then I get the same 'changing constructor arguments' issue. The other alternative seems to be to only let the Application Services layer play with the Repositories, but then you get a lot of boilerplate code added to the Application Services to do very simple things.
These sorts of things make me think I might be doing it wrong. So how should a good Application Services layer be organised?
e.g. Do you have lots of classes that just do one task each? Or do you clump related tasks together along entity lines? How do you deal with tasks that need a lot of repositories? Does needing a lot of repositories for a task mean its time to go back to the drawing board?
First, I'd like to counter your assumption that each entity needs its own repository. Per, Eric Evans "Domain Driven Design"
Repositories give access to selected aggregate roots. Repositories are prohibited from the interior of an aggregate.
Given your example, a dog has a set of tricks that it has learned. When you want to add a new trick to the dog, you'd do something like this:
var dog = dogRepository.Get(dogId);
dog.Tricks.Add(newTrick);
dogRepository.SaveOrUpdate(dog);
When I need a new Application Services method that uses a combination of repositories that I don't have yet,
I'm not sure what you mean by this. But I think if you stick to using repositories for aggregate roots, you're not going to run into such messy code.
The other alternative seems to be to
only let the Application Services
layer play with the Repositories, but
then you get a lot of boilerplate code
added to the Application Services to
do very simple things.
Controllers orchestrate. Think of controllers as a part of the UI, they move you from page to page. I will admit that for simple things, it seems simpler to just inject a repository into the controller, but when your project grows the separation will help a lot, especially if you end up having another application hook into your Tasks layer. Keep repositories out of controllers.
e.g. Do you have lots of classes that
just do one task each? Or do you clump
related tasks together along entity
lines? How do you deal with tasks that
need a lot of repositories? Does
needing a lot of repositories for a
task mean its time to go back to the
drawing board?
Again, I think this goes back to defining aggregate roots. Having 4-5 repositories in a task isn't that big of a deal. I usually organize my tasks by what the application is trying to do, with the idea that if the UI changes to, say, an external JSON request, you just need to call the right task.
Hope this answers your question. Feel free to post this on the Sharp mailing list, you might get a better response there.
Edit based on comments:
Check out Who Can Help Me (https://github.com/sharparchitecture/Who-Can-Help-Me) for an example of how to use the ApplicationServices/Tasks layer. They have a fairly small domain model so each entity has its own task.
I think you're confusing terminology a bit, or perhaps I'm being unclear. The idea behind an ApplicationServices layer is to further abstract the UI from the domain layer. Repositories are domain layer entities, and knowledge of them should not be in the controller. If you end up swapping out ORM or even moving to a document-based storage system, you'll see why this abstraction makes it really convenient, you just need to make sure your ApplicationServices contracts are working and don't have to muck about in the controllers.
But, don't confuse the need for ApplicationServices as a way of future proofing. It simply allows for further decoupling between your layers and decoupling is nearly always a good thing.
Again, for a project you're working on solo, all this might seem a bit of overkill. When you're working with other developers, all this abstraction is really, really nice. You can have a team working on upstream domain issues, and a team working on the presentation layer, and have a nice separation of concerns.
Have you heard about Abstract Factory pattern? It solves this problem in a nice way:
public interface IDalFactory
{
// One way
IRepository<Trick> TrickRepository { get; }
IRepository<Dog> DogRepository { get; }
...
// Other way
IRepository<T> GetRepository<T>();
}
public DogTasks
{
public DogTasks(IDalFactory dalFactory)
{
...
}
}
It is up to you how do you implement IDalFacotry. I usually using lazy initialization of repositories. Once repository is created it is internally stored and reused. One factory instance is created per http request.
The cons is that you don't have control over factories exposed to your application service. But that are your choices. Adding new repositories to constructor or using factory.

Mocking a Controller dependency with Moq using specflow

I am new to specflow and a have a doubt about how to mock my
controller dependencies.
For instance I have a UserController class which depends on my
UserRepository class that a pass to the controller class on its
constructor.
So using Moq I am doing something like this:
var mock = new Mock<UserRepository>();
mock.Setup(m => m.ListAll()).Returns(new List<User>());
var browser = new IE(string.Format("http://localhost:4265/{0}",
username));
But my controller is not using the mocked object, how should I do
that?
Thanks
You are mixing three (atleast) test framework, which ofcourse is cool, but you should probably stop and consider what it is you want to test.
Watin is good for testing your UI as it controls a browser instance. I find it good at making regression tests http://en.wikipedia.org/wiki/Regression_testing
Specflow is great as well - personally i like to use it for closing the gap between business developers and (us) software developers as we can actually define requirements in terms we both understand (and probably other parts of the organization as well) I don't want to start a flame war, but it can introduce more problems than it solves, unless you focus on its real values. We use this at work by testing the service layer (one layer below the controllers in the presentation layer) and we actually only mock the database, external services and file system etc - which makes our specflow tests some kind of integration tests.
Moq is a mocking framework and can ofcourse be used in any kind of tests (like i just let it slip we do) but this is such a great tool for unit testing.
So to return to your question. If you want to make one test to find all your bugs, you're in trouble ;) I know you don't want that - that was just a silly suggestion i made - but really, if you just want to do integration tests (tests running from the UI down through several layers/dependencies) you could easily mix different testing frameworks like you are now, but then why mock the user repository? Is that because you don't want to hit the database?
Anyways one way to do the integration test you seem like you want would be to configure your solution to use a mock - or perhaps a stub would do (create a fake userrepository that returns the data you want to test with) - you should use a Dependency framework like Unity, Ninject or structure map (boy let's not start a war about what framework to use) and have the test url Watin is using launch your site using a configuration with the fake/mock repositories.
You could on the other hand do unit testing on your controllers, services etc. You might even want to try out TDD but that's a whole other chapter i can't cover here!
You are not doing anything with the mock to inject it into your controller. Your controller needs to be given the user repository in order for it to be used.
Also you need to accept more answers.

Resources