I'm developing my own simple IoC library which one i'd like to make thread-safe.
My typical unit test looks like this:
[TestMethod]
public void TestContainerUseExistingObjectFromLifetimeManagerWithFactoryMethod()
{
// Arrange
var container = new FsContainer();
container
.For<IRepository>()
.Use(ctx => new Repository("sql_connection_string"), new ContainerControlledLifetimeManager());
// Act
var first = container.Resolve<IRepository>();
var second = container.Resolve<IRepository>();
// Arrange
Assert.AreEqual(first.ConnectionString, "sql_connection_string");
Assert.AreEqual(second.ConnectionString, "sql_connection_string");
Assert.AreSame(first, second);
}
This works great before i tried to test it next manner:
[TestMethod]
public async Task TestMultiThreadContainerUseExistingObjectFromLifetimeManagerWithFactoryMethodAsync()
{
// Arrange
var container = new FsContainer();
container
.For<IRepository>()
.Use(ctx => new Repository("sql_connection_string"), new ContainerControlledLifetimeManager());
// Act
var instances = await Task.WhenAll(
Task.Run(() => container.Resolve<IRepository>()),
Task.Run(() => container.Resolve<IRepository>())
);
var first = instances[0];
var second = instances[1];
// Arrange
Assert.AreEqual(first.ConnectionString, "sql_connection_string");
Assert.AreEqual(second.ConnectionString, "sql_connection_string");
Assert.AreSame(first, second);
}
This test show me, that i had issue with Assert.AreSame
(my first & second instances were not same).
I've implemented lock
statement at Resolve method and everything started to work fine.
Question: Is it the correct way to duplicate most of the functionality in single
and multi-thread
way to test thread-safity? Does it make sense?