Mugen
Mugen

Reputation: 9085

Verify Autofac registrations in a unit test

I'm registering many types to my Container, implementing all sorts of interfaces.

In some programmatic manner, I want to have a unit test that will check all resolving are successful, meaning there are no circular or missing dependencies in the registrations.

I tried to add something like this:

[TestMethod]
public void Resolve_CanResolveAllTypes()
{
    foreach (var registration in _container.ComponentRegistry.Registrations)
    {
        var instance = _container.Resolve(registration.Activator.LimitType);
        Assert.IsNotNull(instance);
    }
}

But it fails on first run on resolving Autofac.Core.Lifetime.LifetimeScope, though I have methods that accepts ILifetimeScope as parameter and get it just fine when my application starts.

Upvotes: 9

Views: 5654

Answers (2)

Mustafa Düman
Mustafa Düman

Reputation: 152

I have some "keyed" registrations so i have just modified your answer so that it can handled "Keyed" registrations as follows.

foreach (var componentRegistration in _container.ComponentRegistry.Registrations)
{
    foreach (var registrationService in componentRegistration.Services)
    {
        if (registrationService is Autofac.Core.TypedService)
        {
            var registeredTargetType = registrationService.Description;
            var type = GetType(registeredTargetType);
            if (type == null)
            {
                Assert.Fail($"Failed to parse type '{registeredTargetType}'");
            }
            var instance = _container.Resolve(type);
            Assert.IsNotNull(instance);
            Assert.IsInstanceOfType(instance, componentRegistration.Activator.LimitType);
        }
        else if (registrationService is Autofac.Core.KeyedService)
        {
            var keyedService = (KeyedService)registrationService;
            var instance = _container.ResolveKeyed(keyedService.ServiceKey, keyedService.ServiceType);
            Assert.IsNotNull(instance);
            Assert.IsInstanceOfType(instance, componentRegistration.Activator.LimitType);
        }
        else
        {
            throw new NotImplementedException("Unhandled case");
        }
    }
}

Upvotes: 3

Mugen
Mugen

Reputation: 9085

Following code finally worked for me:

private IContainer _container;

[TestMethod]
public void Resolve_CanResolveAllTypes()
{
    foreach (var componentRegistration in _container.ComponentRegistry.Registrations)
    {
        foreach (var registrationService in componentRegistration.Services)
        {
            var registeredTargetType = registrationService.Description;
            var type = GetType(registeredTargetType);
            if (type == null)
            {
                Assert.Fail($"Failed to parse type '{registeredTargetType}'");
            }
            var instance = _container.Resolve(type);
            Assert.IsNotNull(instance);
            Assert.IsInstanceOfType(instance, componentRegistration.Activator.LimitType);
        }
    }
}

private static Type GetType(string typeName)
{
    var type = Type.GetType(typeName);
    if (type != null)
    {
        return type;
    }
    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
    {
        type = assembly.GetType(typeName);
        if (type != null)
        {
            return type;
        }
    }
    return null;
}

GetType borrowed from https://stackoverflow.com/a/11811046/1236401

Upvotes: 7

Related Questions