haleaurelian / proteusproject

Automatically exported from code.google.com/p/proteusproject
0 stars 0 forks source link

Unneeded DLL dependencies #1

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Copy Proteus.Utility.UnitTest.dll, NDbUnit.Core.dll, and
NDbUnit.SqlClient.dll to a directory where you keep external references 
2. Add a reference to the Proteus.Utility.UnitTest.dll in your project
3. Compile and run your unit tests -> you get an error complaining that
other DLLs are missing such as NDbUnit.MySql.dll, which are not actually
needed.

What is the expected output? What do you see instead?
- Proteus should not force the developer to keep around unneeded DLLs.

What version of the product are you using? On what operating system?
- 1.2.3.26999

Please provide any additional information below.
- The NDbUnit guys made the correct decision by refactoring their DLLs so
that the developer can choose only the required DLLs for their DB platform
(e.g. SQL Server)[1]. Proteus reversed this decision by being directly
dependent on all packaged DLLs for all platforms.

[1]
http://unhandled-exceptions.com/blog/index.php/2009/06/07/ndbunit-refactored-for
-explicit-assembly-dependencies/

Original issue reported on code.google.com by khal...@gmail.com on 6 Jul 2009 at 10:43

GoogleCodeExporter commented 8 years ago
I'm also having the same problem

Original comment by mahmudkh...@gmail.com on 11 Jul 2009 at 7:04

GoogleCodeExporter commented 8 years ago
Could not load file or assembly 'NDbUnit.SqlLite, Version=1.5.0.18984,
Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system 
cannot
find the file specified.
    System.IO.FileNotFoundException: Could not load file or assembly 'NDbUnit.SqlLite,
Version=1.5.0.18984, Culture=neutral, PublicKeyToken=null' or one of its
dependencies. The system cannot find the file specified.

Original comment by mahmudkh...@gmail.com on 11 Jul 2009 at 7:09

GoogleCodeExporter commented 8 years ago
Somewhat ironically, I'm not only the project lead on this project, but am 
*also* 
the project lead on NDbUnit, so when 'the NDbUnit guys made the correct 
decision' to 
refactor the binary dependencies on different database drives out of the core 
assembly, *I'm* the one who actually made that decision ;)

This is an interesting challenge because the reason the dependencies are as 
they are 
in Proteus is because Proteus has to be 'aware' of all the available database 
drivers supported by NDbUnit in order for it to offer (programmatically) the 
choice 
of selecting any one of them at run-time.  For Proteus to be 'aware' of all of 
these, it needs to have a binary reference to each of the database-specific 
libraries that NDbUnit *could* use.

That said, I agree that the annoying side-effect of this (that you have to 
bring 
along with you all of the database-specific NDbUnit dll's even if you only 
intent to 
use just one) is a pretty big 'architectural design flaw' in the way Proteus is 
engineered and so I hereby agree to look into doing some kind of 
refactoring/redesign of Proteus to support the same kind of 'take a dependency 
on 
just what you need' approach that I refactored NDbUnit to use.

Thanks for pointing this out~!

Original comment by sboh...@gmail.com on 13 Jul 2009 at 3:01

GoogleCodeExporter commented 8 years ago
Thanks Steve! And sorry if I didn't notice that you were the project lead on 
those two 
projects. I should've made the correlation :)

The strong-typing of the db client is not needed in my opinion; it just gives 
the 
developer re-assurance while writing the code using intellisense. But I'd say a 
string-based client type is fine, which could be resolved and loaded at runtime 
easily 
(if the required assemblies are there).

Original comment by khal...@gmail.com on 13 Jul 2009 at 1:30

GoogleCodeExporter commented 8 years ago
No problem; I appreciate (and agree with) the point you are making.

Re: how I might address this, I'd be interested to get some feedback on what 
comes to
my mind if you have a sec...

Provide for the main assembly to load the user-selected DB support assembly from
NDbUnit using reflection (run-time-dynamic assembly-loading); I'd have to throw 
if
the user-selected-DB-type was from an assembly that the user failed to
copy/deploy/make available.  Obviously this isn't a problem and I *should* throw
here, but this will mean that I will have to load the assembly and then perform 
an
unsafe typecast from the type found there into an INDbUnit implementation in 
order to
use it in the rest of the code.  If the cast fails, I'll again have to throw 
(also
not a bad thing in this instance).

At the same time, I'm also thinking about separating the Proteus Unit-Test 
assemblies
into two separate libraries -- one for the base class(es) that have nothing to 
do
with database-testing support and another for the class(es) that are really 
about
supporting interaction with NDbUnit.  This would mean that users of Proteus Unit
testing wouldn't *have* to also take an implicit dependency on NDbUnit if they
weren't doing any database-dependent testing.

Thoughts --?

Original comment by sboh...@gmail.com on 13 Jul 2009 at 2:14

GoogleCodeExporter commented 8 years ago
Re the first part of your comment about dynamic loading. I think your approach 
should 
be fine. As you mentioned, you should throw if the required assembly is not 
present, 
or you cannot cast the found type to a specific interface.

One thing I would recommend is not to instantiate the INDbUnitTest 
implementation 
from the core assembly. Instead, I think it's better to delegate this to a type 
in 
the loaded assembly itself; i.e. there should be factory class in each 
implementation 
assembly that instantiates and returns the required interface implementation. 
This 
doesn't solve the problem of typecasting, as I think this is an unavoidable 
side-
effect of reflection, but at least it hides the implementation type.

As for your other point, it may make sense to leave everything in one assembly 
at 
this early stage (I see only one general-purpose unit test base class, and one 
db 
unit test base class). Personally I like to avoid early partitioning of the 
code 
until I have to (or it makes perfect sense). In large projects (such as the one 
I'm 
working on) there are too many assemblies, and it takes a long time to load 
those 
assemblies after each small change in the code, which significantly hampering 
the 
develop-compile-test cycle.

Original comment by khal...@gmail.com on 13 Jul 2009 at 2:58

GoogleCodeExporter commented 8 years ago
fixed in r11 http://code.google.com/p/proteusproject/source/detail?r=11

Original comment by sboh...@gmail.com on 6 Dec 2009 at 11:27