c# - Simple Injector and assembly scanning -
i'm diving process of learning ioc , other patterns , have run issue when trying register open generics based on list of assemblies. i'm building core of framework separate class libraries , have set of test projects declare test classes inheriting framework.
problem framework.test.service dll addpersoncommandhandler : icommandhandler<addpersoncommand>
isn't loaded @ runtime icommandhandler<>
open generic fails find anything. need create addpersoncommandhandler
instance in advance 1 assembly in list , works.
is there simple way force loading?
=========== edit: wireup code in unit test project holds app domain , references other assemblies.
public container setupioc() { var container = new container(); container.register(typeof(iunitofwork), typeof(entityframeworkunitofwork), lifestyle.singleton); var assemblies = appdomain.currentdomain.getassemblies(); container.register(typeof(icommandhandler<>), assemblies); container.verify(); return container; }
iunitofwork
in database.interface.dll icommandhandler<>
in core.dll addpersoncommandhandler
in test.service.dll -- part of suite of projects settings structure mimicking putting real solution , referenced unit tests.
so, what's happening unit or work registration works fine think because i'm specifying unitofwork
directly whereas icommandhandler
interface in core binds. post verify() see unit of work registration on container
. test.service.dll loading addpersoncommandhandler
show can instantiate addpersoncommand
in testinit method.
it seems little mad have manually load dlls project. , matter if scan executing folder dlls, loaded...will loading again play nicely or require careful checks find out if loaded?
you don't have explicitly create instance of addpersoncommandhandler
make sure assembly loaded. have reference type in assembly (such addpersoncommandhandler
) statically in code runs before call appdomain.currentdomain.getassemblies()
. instance:
// load bl assembly type type = typeof(addpersoncommandhandler); container.register(typeof(icommandhandler<>), appdomain.currentdomain.getassemblies());
best keep reference in composition root. ensures no matter container initialized (app_start or integration tests) same assemblies loaded.
a more explicit way make explicit list of assemblies should used registration:
// adding (redundant) namespace of type makes clear // user if type still located in business layer. assembly[] businesslayerassemblies = new[] { typeof(mycomp.myapp.businesslayer.addpersoncommandhandler).assembly } container.register(typeof(icommandhandler<>), businesslayerassemblies); container.register(typeof(iqueryhandler<,>), businesslayerassemblies); container.register(typeof(ieventhandler<>), businesslayerassemblies); container.register(typeof(ivalidator<>), businesslayerassemblies);
i prefer latter approach, because prevents scanning bulk of assemblies never contain useful types, while being explicit assemblies (instead of implicitly referencing type happens load assembly).
Comments
Post a Comment