AutoFac-создание экземпляра незарегистрированной службы с известными службами



Создание экземпляра незарегистрированного сервиса с известными сервисами (ввод их через ctr).



Я хочу избежать загрязнения контейнера.

484   2  

2 ответов:

Вот еще один способ разрешения незарегистрированных конкретных типов из контейнера. Обратите внимание, что все логики поиска и выбора конструктора autofac, все обработчики событий регистрации остаются в силе.

Во-первых, вы определяете этот метод:

    public static object ResolveUnregistered(this IComponentContext context, Type serviceType, IEnumerable<Parameter> parameters)
    {
        var scope = context.Resolve<ILifetimeScope>();
        using (var innerScope = scope.BeginLifetimeScope(b => b.RegisterType(serviceType)))
        {
            IComponentRegistration reg;
            innerScope.ComponentRegistry.TryGetRegistration(new TypedService(serviceType), out reg);

            return context.ResolveComponent(reg, parameters);
        }
    }
Идея состоит в том, что вы получаете регистрацию компонента из производного контекста и разрешаете ее в текущем контексте. Затем вы можете создать несколько удобных перегрузок:
    public static object ResolveUnregistered(this IComponentContext context, Type serviceType)
    {
        return ResolveUnregistered(context, serviceType, Enumerable.Empty<Parameter>());
    }

    public static object ResolveUnregistered(this IComponentContext context, Type serviceType, params Parameter[] parameters)
    {
        return ResolveUnregistered(context, serviceType, (IEnumerable<Parameter>)parameters);
    }

    public static TService ResolveUnregistered<TService>(this IComponentContext context)
    {
        return (TService)ResolveUnregistered(context, typeof(TService), Enumerable.Empty<Parameter>());
    }

    public static TService ResolveUnregistered<TService>(this IComponentContext context, params Parameter[] parameters)
    {
        return (TService)ResolveUnregistered(context, typeof(TService), (IEnumerable<Parameter>)parameters);
    }

Я нашел решение, которое требовало некоторого пользовательского кода. Кое-что специфично для моего приложения, но я думаю, что вы можете получить картину.

Resolve(параметр.ParameterType) будет вызовом к вашему контейнеру.

public object ResolveUnregistered(Type type)
{
    var constructors = type.GetConstructors();
    foreach (var constructor in constructors)
    {
        try
        {
            var parameters = constructor.GetParameters();
            var parameterInstances = new List<object>();
            foreach (var parameter in parameters)
            {
                var service = Resolve(parameter.ParameterType);
                if (service == null) throw new NopException("Unkown dependency");
                parameterInstances.Add(service);
            }
            return Activator.CreateInstance(type, parameterInstances.ToArray());
        }
        catch (NopException)
        {

        }
    }
    throw new NopException("No contructor was found that had all the dependencies satisfied.");
}

Comments

    Ничего не найдено.