Auto Dispose Sql Connections properly - c#

My application is using 3 layers: DAL / Service / UL.
My typical DAL class looks like this:
public class OrdersRepository : IOrdersRepository, IDisposable
{
private IDbConnection _db;
public OrdersRepository(IDbConnection db) // constructor
{
_db = db;
}
public void Dispose()
{
_db.Dispose();
}
}
My service calls the DAL class like this (injecting a database connection):
public class ordersService : IDisposable
{
IOrdersRepository _orders;
public ordersService() : this(new OrdersRepository(new Ajx.Dal.DapperConnection().getConnection()))
{
}
public ordersService(OrdersRepository ordersRepo)
{
_orders = ordersRepo;
}
public void Dispose()
{
_orders.Dispose();
}
}
And then finally within my UI layer, this is how I access my service layer:
public class OrdersController : Controller, IDisposable
{
//
// GET: /Orders/
private ordersService _orderService;
public OrdersController():this(new ordersService())
{
}
public OrdersController(ordersService o)
{
_orderService = o;
}
void IDisposable.Dispose()
{
_orderService.Dispose();
}
}
This all works good. But as you can see, I am relying on IDisposable within every layer. UI disposes service object and then service object disposes DAL object and then DAL object disposes the database connection object.
I am sure there has to be a better way of doing it. I am afraid users can forget to dispose my service object (within UI) and I will end up with many open database connections or worse. Please advise the best practice. I need a way to auto-dispose my database connections OR any other unmanaged resources (files etc).

Your question comes back to the principle of ownership:
he who has ownership of the resource, should dispose it.
Although ownership can be transferred, you should usually not do this. In your case the ownership of the IDbConnection is transferred from the ordersService to the OrdersRepository (since OrdersRepository disposes the connection). But in many cases the OrdersRepository can't know whether the connection can be disposed. It can be reused throughout the object graph. So in general, you should not dispose objects that are passed on to you through the constructor.
Another thing is that the consumer of a dependency often can't know if a dependency needs disposal, since whether or not a dependency needs to be disposed is an implementation detail. This information might not be available in the interface.
So instead, refactor your OrdersRepository to the following:
public class OrdersRepository : IOrdersRepository {
private IDbConnection _db;
public OrdersRepository(IDbConnection db) {
_db = db;
}
}
Since OrdersRepository doesn't take ownership, IDbConnection doesn't need to dispose IDbConnection and you don't need to implement IDisposable. This explicitly moves the responsibility of disposing the connection to the OrdersService. However, ordersService by itself doesn't need IDbConnection as a dependency; it just depends on IOrdersRepository. So why not move the responsibility of building up the object graph out of the OrdersService as well:
public class OrdersService : IDisposable {
private readonly IOrdersRepository _orders;
public ordersService(IOrdersRepository ordersRepo) {
_orders = ordersRepo;
}
}
Since ordersService has nothing to dispose itself, there's no need to implement IDisposable. And since it now has just a single constructor that takes the dependencies it requires, the class has become much easier to maintain.
So this moves the responsibility of creating the object graph to the OrdersController. But we should apply the same pattern to the OrdersController as well:
public class OrdersController : Controller {
private ordersService _orderService;
public OrdersController(ordersService o) {
_orderService = o;
}
}
Again, this class has become much easier to grasp and it doesn't needs to dispose anything, since it doesn't has or took ownership of any resource.
Of course we just moved and postponed our problems, since obviously we still need to create our OrdersController. But the difference is that we now moved the responsiblity of building up object graphs to a single place in the application. We call this place the Composition Root.
Dependency Injection frameworks can help you making your Composition Root maintainable, but even without a DI framework, you build your object graph quite easy in MVC by implementing a custom ControllerFactory:
public class CompositionRoot : DefaultControllerFactory {
protected override IController GetControllerInstance(
RequestContext requestContext, Type controllerType) {
if (controllerType == typeof(OrdersController)) {
var connection = new Ajx.Dal.DapperConnection().getConnection();
return new OrdersController(
new OrdersService(
new OrdersRepository(
Disposable(connection))));
}
else if (...) {
// other controller here.
}
else {
return base.GetControllerInstance(requestContext, controllerType);
}
}
public static void CleanUpRequest() }
var items = (List<IDisposable>)HttpContext.Current.Items["resources"];
if (items != null) items.ForEach(item => item.Dispose());
}
private static T Disposable<T>(T instance)
where T : IDisposable {
var items = (List<IDisposable>)HttpContext.Current.Items["resources"];
if (items == null) {
HttpContext.Current.Items["resources"] =
items = new List<IDisposable>();
}
items.Add(instance);
return instance;
}
}
You can hook your custom controller factory in the Global asax of your MVC application like this:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
ControllerBuilder.Current.SetControllerFactory(
new CompositionRoot());
}
protected void Application_EndRequest(object sender, EventArgs e)
{
CompositionRoot.CleanUpRequest();
}
}
Of course, this all becomes much easier when you use a Dependency Injection framework. For instance, when you use Simple Injector (I'm the lead dev for Simple Injector), you can replace all of this with the following few lines of code:
using SimpleInjector;
using SimpleInjector.Integration.Web;
using SimpleInjector.Integration.Web.Mvc;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
var container = new Container();
container.RegisterPerWebRequest<IDbConnection>(() =>
new Ajx.Dal.DapperConnection().getConnection());
container.Register<IOrdersRepository, OrdersRepository>();
container.Register<IOrdersService, OrdersService>();
container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
container.Verify();
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
}
There are a few interesting things going on in the code above. First of all, the calls to Register tell Simple Injector that they need to return a certain implementation should be created when the given abstraction is requested. Next, Simple Injector allows registering types with the Web Request Lifestyle, which makes sure that the given instance is disposed when the web request ends (just as we did in the Application_EndRequest). By calling RegisterMvcControllers, Simple Injector will batch-register all Controllers for you. By supplying MVC with the SimpleInjectorDependencyResolver we allow MVC to route the creation of controllers to Simple Injector (just as we did with the controller factory).
Although this code might be a bit harder to understand at first, the use of a Dependency Injection container becomes really valuable when your application starts to grow. A DI container will help you keeping your Composition Root maintainable.

Well, if you're really paranoid about that you can use the finalizer (destructor) to automatically execute the Dispose when the object is being garbage collected. Check this link which explains basically all you need to know about IDisposable, skip to the Examples section if just want a quick sample how to do that. The finalizer(destructor) is the ~MyResource() method.
But any way, you should always encourage the consumers of your libraries to use correctly the Dispose. The automatic cleaning up, by means of garbage collector still presents flaws. You don't know when the garbage collector will do its job, so if you get lots of these classes instantiated and used, then forgotten, in a short time, you may still be in trouble.

Related

Multiple scopes in the application using Autofac

I have a question concerning lifetime scopes in Autofac.
It is allowed to create multiple scopes in different places in the application to resolve types?
In official documentation there is such a statement:
Note: generally speaking, service location is largely considered an anti-pattern That is, manually creating scopes everywhere and sprinkling use of the container through your code is not necessarily the best way to go. Using the Autofac integration libraries you usually won’t have to do what we did in the sample app above. Instead, things get resolved from a central, “top level” location in the application and manual resolution is rare. Of course, how you design your app is up to you.
What if I have several view models and I need to resolve some types in each one?
Example:
public class ClassA
{
//some code here
}
public class ClassB
{
//some code here
}
public class ClassC
{
//some code here
}
public class ViewModelA
{
public ViewModelA()
{
}
public void Method()
{
//some code here
using (var scope = Container.BeginLifetimeScope())
{
var typeC = scope.Resolve<ClassC>();
//some code here
}
}
}
public class ViewModelB
{
public ViewModelB()
{
}
public void Method()
{
//some code here
using (var scope = Container.BeginLifetimeScope())
{
var typeA = scope.Resolve<ClassA>();
var typeB = scope.Resolve<ClassB>();
//some code here
}
}
}
Assuming that all types are registered in the container - is spreading such scopes across the app is a good practice? How do you understand that?
Best regards.
TL;DR
I have a question concerning lifetime scopes in Autofac. It is allowed to create multiple scopes in different places in the application to resolve types?
Yes, it is allowed, even though it is considered not the best way to go - but definitely not the prohibited one.
What if I have several view models and I need to resolve some types in each one?
Just resolve them through constructor injection as it was suggested by #Raymond. You don't need scopes for something as simple as just resolving stuff.
Now, let's talk this through a little bit.
First of all, how do you use constructor injection? There's nothing simpler than that. Let's modify your example just a bit:
public class ClassA
{
//some code here
}
public class ClassB
{
//some code here
}
public class ClassC
{
//some code here
}
public class ViewModelA
{
private ClassC typeC;
// this is a constructor injection - yes, it's that simple.
public ViewModelA(ClassC _typeC)
{
typeC = _typeC;
}
public void Method()
{
typeC.doStuff();
}
}
public class ViewModelB
{
private ClassA typeA;
private ClassB typeB;
public ViewModelB(ClassA _typeA, ClassB _typeB)
{
typeA = _typeA;
typeB = _typeB;
}
public void Method()
{
typeA.doStuff();
typeB.doAnotherStuff();
}
}
That's it. You just specify parameters in the constructor and save those parameters somewhere in the private fields of the class - and you're good to go. Just use those objects assuming they do exist for sure. (They can be optional though, but I'll skip that for now). If autofac is unable to resolve some dependency it will throw an exception - thus if your class got created you can be absolutely sure that all the dependencies were resolved and provided to it in the constructor parameters. (Again, I'll skip some more complicated scenarios for the sake of brevity and clarity).
What does it give us? Well, now classes ViewModelA and ViewModelB know nothing about any containers or DI in general. All they know is that someone (read: "container") will somehow provide a couple of parameters of specified types (which are usually interfaces) from outside. The class itself now knows nothing about who will create its dependencies, where, when and how - it's not its concern anymore. This is the whole point of dependency injection: removing the concern of managing dependencies.
Next thing is - where are the scopes in this picture? Well... nowhere. :) That's the ideal picture: the services are completely unaware of the existence of the DI container.
But what is a lifetime scope anyways? It is a mean of controlling (surprise!) life time of the objects that are resolved from it. You typically don't need it, unless you are dealing with some edge-case scenarios.
Let's take a look at the extremely simplified example. Say, you have some job that needs to perform some kind of requests to external resources on schedule. However, the method that performs requests is actually generic: it does not know beforehand what exact type of request it is performing because it is defined by the type parameter of the method which will only be known in the runtime.
Also, let's say that you have another requirement: you need to not keep api services in the memory but rather create them only for performing the request and then discard them right away after work is done.
It could look something like the following:
abstract class SomeSpecialApi<TSomeTypeParam> { // just some common base type
public abstract string doGetStuff();
}
class SomeSpecialApi1 : SomeSpecialApi<SomeTypeParam1> where SomeTypeParam1 : TSomeTypeParam {
private HttpClient _client;
public SomeSpecialApi(HttpClient client) {
_client = client;
}
public override string doGetStuff() {
return _client.get(someUrlWeDontCareAbout).Result;
}
}
class SomeSpecialApi2 : SomeSpecialApi<SomeTypeParam2> where SomeTypeParam2 : TSomeTypeParam {
private SomeFtpClient _client;
public SomeSpecialApi(SomeFtpClient client) {
_client = client;
}
public override string doGetStuff() {
// it's just something very different from the previous class
return _client.read(someOtherPathWeDontCareAboutEither).Result;
}
}
class JobPerformer {
private ILifeTimeScope _scope;
public JobPerformer(ILifeTimeScope scope) {
_scope = scope;
}
void PerformJob<T>() {
while (true) {
using (var childScope = scope.BeginLifeTimeScope()) {
var api = childScope.Resolve<SomeSpecialApi<T>>();
var result = api.doGetStuff();
// do something with the result
} // here the childScope and everything resolved from it will be destroyed
// and that's the whole purpose of the lifetime scopes.
Thread.Sleep(1000);
}
}
}
Do you see how it works? Depending on the method's type parameter container will resolve different classes to get the job done. So, instead of creating all the dependencies and then destroying them manually all you need to do is to create your own scope, request an instance of the service you need and then destroy scope after work is done. Scope destruction takes care of destroying all the dependencies which you don't (and shouldn't) even know about. That's definitely an improvement compared to the creation of all the dependencies manually.
However, the disadvantage here is that now JobPerformer class has to know about such a thing as ILifeTimeScope. So it's in some sense similar to the ServiceLocator pattern: we have to know at least who to ask for the dependency, in other words: JobPerformer now knows something about our container. That's what we ideally want to avoid, and there are also other means to achieve it: factories; owned instances; different lifetime policies of service registrations in the container; different kinds of lifetime scopes (at least in autofac); etc.

how Dispose() works inside my Controller and Repository classes

I am working on asp.net mvc-4 web application and entity framework 5.0. now i am confused on how Dispose is working inside my application. currently i have the following settings:-
-I have a APIRepository class which contain multiple methods that use WebClient() to do external API calls. and i do not define any Dispose method inside this class.
public class APIRepository
{
public string AddTicket(string title, string technichian,string account,string site,string description,string mode,string requestor)
{
//code goes here
using (var client = new WebClient())
{
}
return result;
}
//code goes here
}
-I have a Repository class which contain my data access logic, and it initiate my DbContext, and i define a Dispose method inside this class.
public class Repository
{
private MyEntities my = new MyEntities();
//code goes here...
public void Dispose()
{
my.Dispose();
}
-I have a Controller class, which initiate the two repository classes:-
[RequireHttps]
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
//code goes here
protected override void Dispose(bool disposing)
{
if (disposing)
{
repository.Dispose();
}
base.Dispose(disposing);
}
now i have the following questions about my current project:-
Based on my understanding on how Dispose works, is that when an action method calls a View, then asp.net mvc will automatically calls the Dispose method inside my current Controller class. which in turn calls the Dispose method inside my repository , which will make sure that the database connection is closed. so is my understanding valid ?
in my case do i need to have a Dispose method inside my APIRepository() , which as i mentioned this repository only have WebClient() calls to integrate with 3rd party application, and it will return object or simple string to the action method.??
what are the operations that need to be Disposed? as i know calling a my.Dispose(); inside my repository class will make sure that the database connection is closed.. but are there other operations that need to be disposed? such as initiating a WebClient() or returning a JSON by my action method?
what are the actions other than returning a View will call the Dispose method inside my Controller class ?
If you use dependency injection then none of the classes would be responsible for creating or disposing the dependencies injected into it.
Instead of this:
public class ServerController : Controller
{
Repository repository = new Repository();
APIRepository APIrepository = new APIRepository();
where ServerController creates its dependencies and is responsible for disposing of them, this:
public class ServerController : Controller
{
private readonly Repository _repository;
private readonly APIRepository _apiRepository;
public ServerController(Repository repository, APIRepository apiRepository)
{
_repository = repository;
_apiRepository = apiRepository;
}
Now whatever creates an instance of ServerController is responsible for instantiating those objects and disposing of them. That "whatever" is typically your dependency injection container, like Windsor or Unity. Or even better, in ASP.NET Core it's built in and you don't need to add a separate container.
The short version: The container creates your repository, and if it needs to be disposed, it disposes it. You can even specify details about the lifetime of certain dependencies. If it's not disposable and can be reused then it's a singleton. You can create and dispose a new instance every time you need one. Or you can create a new instance that's tied to a given web request. That request uses it and then it's disposed.
which will make sure that the database connection is closed. so is my understanding valid ?
Your database connection is closed way before the dispose method is called. It would be a very rare circumstance that it is not.
in my case do i need to have a Dispose method inside my APIRepository()
Only if you are managing the disposable of objects at field level instead of a method level.
// The method is disposing of the object
public class NotDisposable
{
public string GetString()
{
string result;
// This is disposed by the time the method exists.
using(var disposable new Disposable)
{
result = disposable.GetString()
}
return result;
}
}
// This class has a field that it needs to dispose
// so it inherites from IDisposable
public class Disposable : IDisposable
{
private bool _isDisposed;
private readonly IDisposable _somethingToManuallyDispose;
public Disposable()
{
somethingToManuallyDispose = new SomethingImplementsIDisposable();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing && !_isDisposed)
{
_isDisposed = true;
// Dispose Managed Resources
if (_somethingToManuallyDispose != null)
{
_somethingToManuallyDispose.Dispose();
}
}
}
}
but are there other operations that need to be disposed?
Example above, where you do not Dispose of an object in the method.
what are the actions other than returning a View will call the Dispose method inside my Controller class
That sentence doesn't even make sense. Returning a View does not call Dispose. The MVC/API Pipeline Disposes of the controller after the response is sent to the client, and only if it implements IDisposable.
Please consider reading MSDN - Dispose Pattern and MSDN - Implementing a Dispose Method and MSDN - Using Objects That Implement IDisposable.

Proper use of "Using" statement for datacontext

I’m using Linq to Entities and lately, I found that a lot of folks recommending wrapping the datacontext in a using statement like this:
Using(DataContext db = new DataContext) {
var xx = db.customers;
}
This makes sense. However, I’m not sure how to incorporate this practice in my model.
For example: I have an interface (let’s call it customer) and it is implemented by a repository like this:
namespace Models
{
public class rCustomer : iCustomer
{
readonly DataContext db = new DataContext();
public customer getCustomer(Guid id)
{
return db.customers.SingleOrDefault(por => por.id == id);
}
public iQueryable<customer> getTopCustomers()
{
return db.customers.Take(10);
}
//*******************************************
//more methods using db, including add, update, delete, etc.
//*******************************************
}
}
Then, to take the advantage of using, I will need to change the methods to look like this:
namespace Models
{
public class rCustomer : iCustomer
{
public customer getCustomer(Guid id)
{
using(DataContext db = new DataContext()) {
return db.customers.SingleOrDefault(por => por.id == id);
}
}
public iQueryable<customer> getTopCustomers()
{
using(DataContext db = new DataContext()) {
return db.customers.Take(10);
}
}
//*******************************************
//more methods using db
//*******************************************
}
}
My question is: the recommendation of using “Using” is really that good? Please take in consideration that this change will be a major one, I have about 25 interfaces/repository combos, and each has about 20-25 methods, not to mention the need to re-test everything after finish.
Is there other way?
Thanks!
Edgar.
You can implement a Database factory which will cause your DbContext is being reused.
You can achieve this as follows:
DatabaseFactory class:
public class DatabaseFactory : Disposable, IDatabaseFactory
{
private YourEntities _dataContext;
public YourEntities Get()
{
return _dataContext ?? (_dataContext = new YourEntities());
}
protected override void DisposeCore()
{
if (_dataContext != null)
_dataContext.Dispose();
}
}
Excerpt of the Repository base class:
public abstract class Repository<T> : IRepository<T> where T : class
{
private YourEntities _dataContext;
private readonly IDbSet<T> _dbset;
protected Repository(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
_dbset = DataContext.Set<T>();
}
protected IDatabaseFactory DatabaseFactory
{
get;
private set;
}
protected YourEntities DataContext
{
get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
}
Your table's repository class:
public class ApplicationRepository : Repository<YourTable>, IYourTableRepository
{
private YourEntities _dataContext;
protected new IDatabaseFactory DatabaseFactory
{
get;
private set;
}
public YourTableRepository(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{
DatabaseFactory = databaseFactory;
}
protected new YourEntities DataContext
{
get { return _dataContext ?? (_dataContext = DatabaseFactory.Get()); }
}
}
public interface IYourTableRepository : IRepository<YourTable>
{
}
}
This works perfectly together with AutoFac constructor injection as well.
Considering the code provided I see, you esplicitly use readonly DataContext db = new DataContext(); like a global variable, so you consider to have that object lifetime along with your rCustomer class instance lifetime.
If this is true, what you can do, instead of rewriting everything, you can implement IDisposable and inside Dispose() code something like
private void Dispose()
{
if(db != null)
db.Dispose();
}
Hope this helps.
As others have mentioned, it's important for the data contexts to be disposed. I won't go into that further.
I see three possible designs for the class that ensure that the contexts are disposed:
The second solution you provide in which you create a data context within the scope of each method of rCustomer that needs it so that each datacontext is in a using block.
Keep the data context as an instance variable and have rCustomer implement IDisposable so that when rCustomer is disposed you can dispose of it's data context. This means that all rCustomer instances will need to be wrapped in using blocks.
Pass an instance of an existing data context into rCustomer through its constructor. If you do this then rCustomer won't be responsible for disposing of it, the user of the class will. This would allow you to use a single data context across several instances of rCustomer, or with several different classes that need access to the data context. This has advantages (less overhead involved in creating new data contexts) and disadvantages (larger memory footprint as data contexts tend to hold onto quite a lot of memory through caches and the like).
I honestly think option #1 is a pretty good one, as long as you don't notice it performing too slowly (I'd time/profile it if you think it's causing problems). Due to connection pooling it shouldn't be all that bad. If it is, I'd go with #3 as my next choice. #2 isn't that far behind, but it would likely be a bit awkward and unexpected for other members of your team (if any).
The DataContext class is wrapped in a Using statement because it implements the IDisposable interface.
Internal to the DataContext it is using SqlConnection objects and SqlCommand objects. In order to correctly release these connection back to the Sql Connection Pool, they need to be disposed of.
The garbage collector will eventually do this, but it will take two passes due to the way IDisposable objects are managed.
It's strongly encouraged that Dispose is called and the Using statement is a nice way to do this.
Read these links for more indepth explanation:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2625b105-2cff-45ad-ba29-abdd763f74fe/
http://www.c-sharpcorner.com/UploadFile/DipalChoksi/UnderstandingGarbageCollectioninNETFramework11292005051110AM/UnderstandingGarbageCollectioninNETFramework.aspx
An alternative would be to make your rCustomer class implement IDisposable, and then in your Dispose method, you can call Dispose on your DataContext if it is not null. However, this just pushes the Disposable pattern out of your rCustomer class, into whatever types are using rCustomer.

Keep dependency injected objects for async handler in MVC3 application

I am working on a MVC3 application in which I would like to handle some code blocks asynchronously. These code blocks need to perform some db operations and they need access to my DAL repositories which are initiated trough my dependency injection setup. I have set the lifetime of the repository to an "instance per http request" lifetime and I am looking for a way to extend that lifetime for the async operation.
public class AsyncController : Controller
{
private readonly ICommandBus commandBus;
private readonly IObjectRepository objectRepository;
public ActionResult DoThings()
{
DoThingsAsync();
return View();
}
private delegate void DoThingsDelegate();
private void DoThingsAsync()
{
var handler = new DoThingsDelegate(DoThingsNow);
handler.BeginInvoke(null, null);
}
private void DoThingsNow()
{
var objects = objectRepository.getAll();
foreach (Thing thing in objects)
{
thing.modifiedOn = DateTime.Now;
objectRepository.Update(thing);
}
}
}
The objectRepository is initiated for the lifetime of the request and I would like to skip the garbage collection for this object for one method in one controller only. I have tried to pass the repository as a parameter to the method and the delegate but that did not extend its lifetime.
When starting a new thread, it is wise to let the Container compose a totally new object graph for you. When you reuse dependencies that are created in the context of a HTTP request (or thread context or what have you), this can result in race conditions and other sort of failures and strange behavior.
This of course doesn’t have to be the case when you know that those dependencies are thread-safe (or created with a per-request lifetime and are not used by the request after triggering the async operation), but this is not something a consumer of these dependencies should know or should depend on, because it is the responsibility of the part of the application that wires everything together (The Composition Root). Doing this, would also make it harder to change that dependency configuration later on.
Instead, you should refactor your DoThings method into its own class and let your Controller depend on some sort of IDoThings interface. This way you can postpone the decision about handling things asynchronously until the moment you wire everything together. When reusing that logic in another type of application (Windows Service for instance), it even allows you to change the way this operation is executed asynchronously (or simply execute it synchronously).
To go even one step further, the actual DoThings business logic and the part that executes that logic asynchronously are two different concerns: two separate responsibilities. You should separate them into different classes.
Here's an example of what I advise you to do:
Define an interface:
public interface IDoThings
{
void DoThings();
}
Let your Controller depend on that interface:
public class SomeController : Controller
{
private readonly IDoThings thingsDoer;
public SomeController(IDoThings thingsDoer)
{
this.thingsDoer = thingsDoer;
}
public ActionResult DoThings()
{
this.thingsDoer.DoThings();
return View();
}
}
Define an implementation that contains the business logic:
public class DoingThings : IDoThings
{
private readonly ICommandBus commandBus;
private readonly IObjectRepository objectRepository;
public DoingThings(ICommandBus commandBus,
IObjectRepository objectRepository)
{
this.commandBus = commandBus;
this.objectRepository = objectRepository;
}
public void DoThings()
{
var objects = objectRepository.getAll();
foreach (Thing thing in objects)
{
thing.modifiedOn = DateTime.Now;
objectRepository.Update(thing);
}
}
}
Define a proxy that knows how to handle a DoingThings asynchronously:
public class DoingThingsAsync : IDoThings
{
private readonly Container container;
public DoingThingsAsync(Container container)
{
this.container = container;
}
public void DoThings()
{
Action handler = () => DoThingsNow();
handler.BeginInvoke(null, null);
}
private void DoThingsNow()
{
// Here we run in a new thread and HERE we ask
// the container for a new DoingThings instance.
// This way we will be sure that all its
// dependencies are safe to use. Never move
// dependencies from thread to thread.
IDoThings doer =
this.container.GetInstance<DoingThings>();
doer.DoThings();
}
}
Now, instead of injecting a DoingThings into the SomeController, you inject a DoingThingsAsync into the controller. The controller does not know whether the operation is executed synchronously or not, and it doesn't care. Besides that, this way you are also separating your business logic from your presentation logic, which is important for lots of good reasons.
You might want to consider using the command pattern as basis around business operations that mutate state (if you're not already using such a thing, considering the ICommandBus interface). Take for instance a look at this article. With this pattern you can more easily configure certain commands to run asynchronously or batch them to an external transactional queue, for later processing, without having to change any of the consumers of those commands.

Should Dispose methods be unit tested?

I am using C#. Is it advised to unit test dispose methods? If so why, and how should one test these methods?
Yes, but it might be hard. There are two things that can generally happen in Dispose implementation:
Unmanaged resources are released.
In this case it's pretty hard to verify that the code called, for example, Marshal.Release. A possible solution is to inject an object that can do the disposing and pass a mock to it during testing. Something to this effect:
interface ComObjectReleaser {
public virtual Release (IntPtr obj) {
Marshal.Release(obj);
}
}
class ClassWithComObject : IDisposable {
public ClassWithComObject (ComObjectReleaser releaser) {
m_releaser = releaser;
}
// Create an int object
ComObjectReleaser m_releaser;
int obj = 1;
IntPtr m_pointer = Marshal.GetIUnknownForObject(obj);
public void Dispose() {
m_releaser.Release(m_pointer);
}
}
//Using MOQ - the best mocking framework :)))
class ClassWithComObjectTest {
public DisposeShouldReleaseComObject() {
var releaserMock = new Mock<ComObjectReleaser>();
var target = new ClassWithComObject(releaserMock);
target.Dispose();
releaserMock.Verify(r=>r.Dispose());
}
}
Other classes' Dispose method is called
The solution to this might not be as simple as above. In most cases, implementation of Dispose is not virtual, so mocking it is hard.
One way is to wrap up those other objects in a mockable wrapper, similar to what System.Web.Abstractions namespace does for HttpContext class - i.e. defines HttpContextBase class with all virtual methods that simply delegates method calls to the real HttpContext class.
For more ideas on how to do something like that have a look at System.IO.Abstractions project.
Certainly can't hurt. Client code may try to use an object of your class after it has disposed of it. If your class is composed of other IDisposable objects, you should always be throwing the ObjectDisposedException exception if it is in a state which it is no longer usable.
Of course, you should only be testing the external state of your object. In the example below, I've made the property Disposed external to give me the state.
Consider:
internal class CanBeDisposed : IDisposable
{
private bool disposed;
public bool Disposed
{
get
{
if (!this.disposed)
return this.disposed;
throw new ObjectDisposedException("CanBeDisposed");
}
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
//// Dispose of managed resources.
}
//// Dispose of unmanaged resources.
this.disposed = true;
}
}
}
So how I would test this is thus:
CanBeDisposed cbd;
using (cbd = new CanBeDisposed())
{
Debug.Assert(!cbd.Disposed); // Best not be disposed yet.
}
try
{
Debug.Assert(cbd.Disposed); // Expecting an exception.
}
catch (Exception ex)
{
Debug.Assert(ex is ObjectDisposedException); // Better be the right one.
}
If your class creates and works with unmanaged resources, then you should definitely ensure that Dispose works as you expect it to - although it could be argued it is more of an integration test due to the type of hoops you're going to have to jump through.
If your class only creates / uses managed resources ( i.e. they implement IDisposable ) then all you really need to ensure is that the Dispose method on these resources is invoked at the correct time - if you are using some form of DI then you can inject a mock and assert that Dispose was called.
Look at the complexity of your dispose methods - if they are only a couple of lines long with maybe 1 condition, ask yourself if there really is a benefit in unit testing them.
Big yes - if your situation requires you to implement a Dispose function - you better make sure it does what you think!
For example, we have classes that coordinate database tasks (think SSIS packages, but with SqlConnection and SqlCommand and SqlBulkCopy etc.).
If I don't properly implement my Dispose, I could have an uncommitted SqlTransaction, or dangling SqlConnection. This would be VERY bad if I were running multiple instances of these database tasks in series.
As a practical tip (because yes, you should test Dispose()) my experience has been that there are two ways to do so without too much hassle.
IDisposer
The first follows Igor's accepted answer - inject something like an IDisposer, so that you can call
public void Dispose()
{
_disposer.Release(_disposable);
}
where
public interface IDisposer
{
void Release(IDisposable disposable);
}
Then all you need to do is mock the IDisposer and assert that it's called once and you're golden.
Factory
The second, and my personal favourite, is to have a factory that creates the thing you need to test disposal of. This only works when the factory produces a mockable type (interface, abstract class), but hey, that's almost always the case, especially for something that's to be disposed. For testing purposes, mock the factory but have it produce a mock implementation of the thing you want to test disposal of. Then you can assert calls to Dispose directly on your mock. Something along the lines of
public interface IFooFactory
{
IFoo Create(); // where IFoo : IDisposable
}
public class MockFoo : IFoo
{
// ugly, use something like Moq instead of this class
public int DisposalCount { get; privat set; }
public void Dispose()
{
DisposalCount++;
}
}
public class MockFooFactory
{
public MockFoo LatestFoo { get; private set; }
public IFoo Create()
{
LatestFoo = new MockFoo();
return LatestFoo;
}
}
Now you can always ask the factory (which will be available in your test) to give you the latest MockFoo, then you dispose of the outer thing and check that DisposalCount == 1 (although you should use a test framwork instead, e.g. Moq).

Categories

Resources