ioc container - Domain Events Implementation Using StructureMap Error -


i trying grasp fundamentals of raising/handling domain event in solution. using visual studio 2017, .net core 1.1, c#, structuremap 4.5.1.

the failure in code came light in unit test failed when checking if domain event being raised correctly.

my startup.cs class includes following code:

    public iserviceprovider configureservices(iservicecollection services)     {         services.addsingleton(_config);          services.addautomapper();          services.addmvc()             .addcontrollersasservices();          return configureioc(services);     }      public iserviceprovider configureioc(iservicecollection services)     {         var container = new container();          container.configure(config =>         {             config.scan(scan =>             {                 scan.assemblycontainingtype(typeof(startup));                 scan.assembly("shared");                 scan.assembly("taskscheduling");                 scan.assembly("taskscheduling_tests");                 scan.withdefaultconventions();                 scan.connectimplementationstotypesclosing(typeof(ihandle<>));              });              //populate container using service collection             config.populate(services);         });          return container.getinstance<iserviceprovider>();      } 

where possible have been following udi dahan's approach domain events - salvation

my domainevents class implements following interface:

using system;  namespace shared.interfaces {     public interface idomainevent     {         datetime datetimeeventoccurred { get; }     } } 

the domainevents class follows:

using system; using system.collections.generic; using shared.interfaces; using structuremap;  namespace shared {     /// <summary>     /// http://udidahan.com/2009/06/14/domain-events-salvation/     /// http://msdn.microsoft.com/en-gb/magazine/ee236415.aspx#id0400046     ///      /// class registers domain events , makes sure called.     /// </summary>      public static class domainevents     {         [threadstatic]         private static list<delegate> actions;         public static icontainer container { get; set; }          // registers callback given domain event.         public static void register<t>(action<t> callback) t : idomainevent         {             if (actions == null)             {                 actions = new list<delegate>();             }             actions.add(callback);         }          // clears callbacks passed register on current thread.         public static void clearcallbacks()         {             actions = null;         }          // raises given domain event.         public static void raise<t>(t args) t : idomainevent         {             foreach (var handler in container.getallinstances<ihandle<t>>())             {                 handler.handle(args);             }              if (actions != null)             {                 foreach (var action in actions)                 {                     if (action action<t>)                     {                         ((action<t>)action)(args);                     }                 }             }         }    } } 

i have task class when updated raises taskupdatedevent. taskupdatedevent class follows:

using shared.interfaces; using system; namespace taskscheduling.model.events {     public class taskupdatedevent : idomainevent     {         /// <summary>         /// when creating taskupdatedevent have pass in task object.         /// </summary>         /// <param name="task"></param>         public taskupdatedevent(scheduleaggregate.task task)             : this()         {             taskupdated = task;         }         public taskupdatedevent()         {             this.id = guid.newguid();             datetimeeventoccurred = datetime.now; // idomainevent interface requirement.         }          public guid id { get; private set; }         public datetime datetimeeventoccurred { get; private set; }         public scheduleaggregate.task taskupdated { get; private set; }     } } 

and event raised following lines in task class:

var taskupdatedevent = new taskupdatedevent(this); domainevents.raise(taskupdatedevent); 

i have 1 unit test, far, check if event being raised. unit test follows:

using system; using nunit.framework; using shared; using taskscheduling.model.scheduleaggregate; using taskscheduling.model.events;  namespace taskscheduling_tests {     [testfixture]     public class taskupdatedeventshould     {         private task testtask;         private readonly guid testscheduleid = guid.newguid();         private const int testlocationid = 567;         private const int testdeviceid = 123;         private const int testtasktypeid = 1;         private readonly datetime teststarttime = new datetime(2014, 7, 1, 9, 0, 0);         private readonly datetime testendtime = new datetime(2014, 7, 1, 9, 30, 0);         private readonly datetimerange newtasktimerange = new datetimerange(new datetime(2014, 6, 9, 10, 0, 0), timespan.fromhours(1));         private const string testtitle = "unit test title";          [setup]         public void setup()         {             domainevents.clearcallbacks();              testtask = task.create(                 testscheduleid,                 testlocationid,                 testdeviceid,                 testtasktypeid,                 teststarttime,                 testendtime,                 testtitle             );         }          [test]         public void entityconstructor_isnot_null()         {             assert.isnotnull(testtask);         }           [test]         public void raisetaskupdatedevent()         {             // arrange             guid updatedappointmentid = guid.empty;             domainevents.register<taskupdatedevent>(aue =>                 {                     // defines happens when event raised/                     // 'updatedappointmentid' changed being zeros testtask's id value.                     updatedappointmentid = testtask.id;                 });              // act             testtask.updatetime(newtasktimerange);              // assert             assert.areequal(testtask.id, updatedappointmentid);         }      } } 

the failure appears occur in domainevent class when raise method called. debugging shows event raised , arguments set, container null foreach loop cannot check handlers.

i cannot figure out why container null i'm sure must missing obvious. suggestions welcome.


Comments