Force StructureMap to Plug-In a populated Instance During Runtime

24 Views Asked by At

During unit tests, I load-up my Unit-of-Work (UOW) instance with mock data. Then, I hand the Unit-of-Work instance to the class-instances that are being tested.

FOR EXAMPLE:
Below I am loading the UOW with default scenario data...and then...setting the UOW into the newly created WorkfklowProvider (instance)

// ARRANGE
var unitOfWork = Builder.CreateInstance<MeasurementContractsUnitOfWork>();

// Load Data
Builder.DefaultDataScenario.Load(unitOfWork);

// at this point...the UOW is full of testable data

// Set Objects
var workflowProvider = Builder.CreateInstance<WorkflowProvider>();
workflowProvider.UnitOfWork = unitOfWork;

// at this point...I can do my tests

As you can see...with SMALLER tests this isn't a problem. However, for larger tests that have more instances...it can get very "busy".

FOR EXAMPLE:
As such, lets look at a LARGER test...
See how I am having to plug-in the the UOW instance everywhere? I am hoping to avoid this.

// ARRANGE
var unitOfWork = Builder.CreateInstance<MeasurementContractsUnitOfWork>();

// Load Data
Builder.DefaultDataScenario.Load(unitOfWork);

// Set Objects
var workflowProvider = Builder.CreateInstance<WorkflowProvider>();
var builderATF = Builder.CreateInstance<AuthorizationToFlowDocumentDataSetBuilder>();
var providerATF = Builder.CreateInstance<AuthorizationToFlowDocumentProvider>();

workflowProvider.UnitOfWork = unitOfWork;
builderATF.UserManager.UnitOfWork = unitOfWork;
builderATF.WorkflowProvider = workflowProvider;
builderATF.UserMetaDataComponent.UnitOfWork = unitOfWork;
builderATF.UnitOfWork = unitOfWork;

providerATF.MeterProvider.UnitOfWork = unitOfWork;
providerATF.CommentingProvider.UnitOfWork = unitOfWork;
providerATF.DocumentParticipationProvider.UnitOfWork = unitOfWork;
providerATF.FavoritesManager.UnitOfWork = unitOfWork;
providerATF.UserManager.UnitOfWork = unitOfWork;
providerATF.UnitOfWork = unitOfWork;

QUESTION:
Is there a way to tell StructureMap to hand-back the populated Unit-of-Work (UOW) instance to all classes at runtime (after I have populated the UOW)?

Just to be clear...once I have populated the initial UOW instance...I want StructireMap to use that instance for all future CreateInstance calls

1

There are 1 best solutions below

1
Prisoner ZERO On BEST ANSWER

Turns out, all you have to do is use the INJECT method.

[TestMethod]
public void Experimental_UnitTest()
{
    // STEP 1: Create a container within the scope of your individual UnitTest
    var container = IoC.Initialize();
    var unitOfWork = container.GetInstance<MeasurementContractsUnitOfWork>();

    // STEP 2: Load Your Data
    Builder.DefaultDataScenario.Load(unitOfWork);

    // STEP 3: "Inject" your instance
    container.Inject<MeasurementContractsUnitOfWork>(unitOfWork);

    // From here forward...all Instances created will get a copy of the populated UnitOfWork
    // This includes any PROPERTY objects that StructureMap creates within each instance too
    var builderRTF = container.GetInstance<RequestToFlowDocumentDataSetBuilder>();
    var builderATF = container.GetInstance<AuthorizationToFlowDocumentDataSetBuilder>();

}

For those that may want to "see" what is happening in the Load method:
As you can see, you're loading-up the Unit of Work with test data...

public void Load(MeasurementContractsUnitOfWork unitOfWork)
{
    // Lookups
    Load_Area(unitOfWork);
    Load_State(unitOfWork);
    Load_County(unitOfWork);

    // Entities
    Load_Users(unitOfWork);
    
    // etc...
}

private void Load_Area(MeasurementContractsUnitOfWork unitOfWork)
{
    var collection = new List<Area>();

    collection.Add(new Area { Id = 1, AreaName = "East Texas", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });
    collection.Add(new Area { Id = 2, AreaName = "Intrastate", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });
    collection.Add(new Area { Id = 3, AreaName = "Louisana", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });
    collection.Add(new Area { Id = 4, AreaName = "Midcon", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });
    collection.Add(new Area { Id = 5, AreaName = "Northeast", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });
    collection.Add(new Area { Id = 6, AreaName = "North Texas", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });
    collection.Add(new Area { Id = 7, AreaName = "South Texas", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });
    collection.Add(new Area { Id = 8, AreaName = "West Texas", CreateUserId = CREATED_BY_ID, CreateDate = DateTime.Now, UpdateUserId = CREATED_BY_ID, UpdateDate = DateTime.Now, IsActive = true });

    unitOfWork.Area.CreateList(collection);
}