I am working on a DI problem that I think I understand the cause of, but I need some suggestions to work around.
I have built a stand alone assembly that talks to Sql (call this assembly a), and another assembly that contains business logic (call this assembly b). I created an interface for the db class in the b assembly. Since the interface isn't part of the db assembly, I don't need any references to the db project, and I can load a reference to the db assembly or a stub if I want to run unit tests at run time and neither assembly needs to know about the other.
I can write code in the business logic library that compiles that looks like this: (pretend that a and b are namespaces in their respective assemblies)
a.IDatabaseClass db_class = (a.IDatabase)new b.Database();
When I try to run this however, I get an invalid cast exception. I think it compiles because the interface matches the class perfectly, but fails at run time because object signature doesn't see IDatabase in the inheritance chain of the Database class.
In c++ you can get away with casting anything however you want, but c# is a little bit stricter about casting object pointers. Even though the class has all the correct function signatures, it is blowing up because the objects don't match.
Now I could put the db object interface in the assembly with the db object, but then the business logic needs a reference to the db assembly. Also, this just creates complications down the road, because if I write a stub db object in a unit test, I need a reference to the db assembly just for the interface that I am going to use in my test stub object. This doesn't seem to be disentangling couplings by doing this...
I could put all the interfaces in a third assembly that is a parent to the db assembly, the business logic, and the unit tests. This is how you can solve circular dependency issues. However, this ties the db assembly to the parent assembly, and makes it a lot less modular to be used with other projects.
I am open to suggestions about how I can set up each assembly so that they function independently and can be used for DI. I suppose I could keep the test stub objects in the same assembly as the real code, but that seems weird.
Aucun commentaire:
Enregistrer un commentaire