views:

51

answers:

1

I understand one of the (maybe best) ways of using inversion of control is by injecting the dependent objects through the constructor (constructor injection).

However, if I make calls to these objects outside of the object using them, I feel like I am violating some sort of rule - is this the case? I don't think there is any way of preventing that from happening, but should I establish a rule that (outside of mocked objects) we should never call methods from these objects?

[EDIT] Here's a simplified example of what I am doing. I have a FileController object that basically is used for cataloging files. It uses a FileDal object that talks to the database to insert/query/update File and Directory tables.

On my real implementation I build the controller by instructing Castle to use a SQL Server version of the DAL, in my unit test I use an in-memory Sqlite version of the DAL. However, due to the way the DAL is implemented, I need to call BeginTransaction and Commit around the usage of the FileController so the connection does not get closed and I can later make retrievals and asserts. Why I have to do that is not much important, but it led me to think that calling methods on a DAL object that is used by other clients (controllers) didn't sound kosher. Here's an example:

FileDal fileDal = CastleFactory.CreateFileDal();
fileDal.BeginTransaction();
FileController fileController = new FileController(fileDal);
fileController.CallInterestingMethodThatUsesFileDal();
fileDal.Commit();
+2  A: 

It really depends on the type of object - but in general, I'd expect that to be okay.

Indeed, quite often the same dependency will be injected into many objects. For example, if you had an IAuthenticator and several classes needed to use authentication, it would make sense to create a single instance and inject it into each of the dependent classes, assuming they needed the same configuration.

I typically find that my dependencies are immutable types which are naturally thread-safe. That's not always the case, of course - and in some cases (with some IoC containers, at least) you may have dependencies automatically constructed to live for a particular thread or session - but "service-like" dependencies should generally be okay to call from multiple places and threads.

Jon Skeet
Thank you, Jon. In my case they are mostly DAL objects and you are indeed correct, they are created through Castle and then passed to various "controllers". I asked because I am writing unit tests and I had to initiate and terminate a transaction *outside* of the client object and that didn't feel right. Oh btw, I am *not* talking to a real database, I am running unit tests with in-memory Sqlite.
Otávio Décio