Разрешать зависимости только из указанного пространства имен

Я могу автоматически регистрировать все типы, реализующие интерфейсы с этим выражением

IUnityContainer container = new UnityContainer();

container.RegisterTypes(
    AllClasses.FromAssembliesInBasePath(),
    WithMappings.FromMatchingInterface,
    WithName.Default,
    WithLifetime.Transient);
ICustomer result = container.Resolve<ICustomer>();

Как я могу указать пространство имен для интерфейсов и реализаций?

i.e: только интерфейсы в Framework.RepositoryInterfaces должны быть разрешены типами в Framework.RepositoryImplementations.

Ответ 1

Вы можете использовать RegistrationConvention:

public class NamespaceRegistrationConvention : RegistrationConvention
{
    private readonly IEnumerable<Type> _typesToResolve;
    private readonly string _namespacePrefixForInterfaces;
    private readonly string _namespacePrefixForImplementations;

    public NamespaceRegistrationConvention(IEnumerable<Type> typesToResolve, string namespacePrefixForInterfaces, string namespacePrefixForImplementations)
    {
        _typesToResolve = typesToResolve;
        _namespacePrefixForInterfaces = namespacePrefixForInterfaces;
        _namespacePrefixForImplementations = namespacePrefixForImplementations;
    }

    public override IEnumerable<Type> GetTypes()
    {
        // Added the abstract as well. You can filter only interfaces if you wish.
        return _typesToResolve.Where(t =>
            ((t.IsInterface || t.IsAbstract) && t.Namespace.StartsWith(_namespacePrefixForInterfaces)) ||
            (!t.IsInterface && !t.IsAbstract && t.Namespace.StartsWith(_namespacePrefixForImplementations)));
    }

    public override Func<Type, IEnumerable<Type>> GetFromTypes()
    {
        return WithMappings.FromMatchingInterface;
    }

    public override Func<Type, string> GetName()
    {
        return WithName.Default;
    }

    public override Func<Type, LifetimeManager> GetLifetimeManager()
    {
        return WithLifetime.Transient;
    }

    public override Func<Type, IEnumerable<InjectionMember>> GetInjectionMembers()
    {
        return null;
    }
}

И используйте его через:

container.RegisterTypes(new NamespaceRegistrationConvention(AllClasses.FromAssembliesInBasePath(), "Framework.RepositoryInterfaces", "Framework.RepositoryImplementations");
ICustomer result = container.Resolve<ICustomer>();

Ответ 2

Попробовать типы фильтрации по пространству имен

IUnityContainer container = new UnityContainer();

container.RegisterTypes(
    AllClasses.FromAssembliesInBasePath().Where(
    t => t.Namespace.StartsWith("Framework.RepositoryImplementations") ||
    t.Namespace.StartsWith("Framework.RepositoryInterfaces")),
    WithMappings.FromMatchingInterface,
    WithName.Default,
    WithLifetime.Transient);

ICustomer result = container.Resolve<ICustomer>();