【问题标题】:Resolve a class instance which takes parameters in constructor at run time using autofac使用 autofac 解析在运行时在构造函数中接受参数的类实例
【发布时间】:2018-02-06 03:00:20
【问题描述】:

我正在按照下面的示例使用 autofac 在运行时创建一个类实例。 http://autofaccn.readthedocs.io/en/latest/advanced/delegate-factories.html

但是在本地运行时,我看到了一个异常。我是 autofac 的新手,如果我在这里做错了什么或者您需要更多信息,请告诉我。

代码结构:

public class ClassName
{
    public delegate ClassName Factory(Type1 obj1, string obj2);
    public ClassName(Type1 obj1, string obj2)
    {
        this.type1 = obj1;
        this.type2= obj2;
    }

    /*Some methods of this class that use type1 and type2*/
}

// Registration 
container.RegisterType<Type1>();
container.RegisterType<ClassName.Factory>();
container.RegisterType<ClassName>().AsSelf().InstancePerDependency();

// In some method to create an instance of ClassName
var factory = container.Resolve<Factory>(); // This is throwing the following exception.
var instance = factory(obj1Instance, "text"); // obj1Instance and "text" parameters cannot be determined at registration time.

异常堆栈跟踪:

Logging handled exception: Autofac.Core.DependencyResolutionException: Autofac.Core.DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = Factory (ReflectionActivator), Services = [ClassName+Factory], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ClassName+Factory' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Object object' of constructor 'Void .ctor(System.Object, IntPtr)'. (See inner exception for details.) ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ClassName+Factory' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Object object' of constructor 'Void .ctor(System.Object, IntPtr)'.
   at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   --- End of inner exception stack trace ---
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
   at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)

【问题讨论】:

    标签: c# dependency-injection autofac autofac-configuration


    【解决方案1】:

    您遇到的问题是您正在尝试注册工厂。 Autofac 了解如何解析委托,但不了解如何注册。

    这应该可行:

    public class ClassName
    {
        public delegate ClassName Factory(Type1 obj1, string obj2);
        public ClassName(Type1 obj1, string obj2)
        {
            this.type1 = obj1;
            this.type2= obj2;
        }
    }
    
    // Registration 
    container.RegisterType<ClassName>().AsSelf().InstancePerDependency();
    
    // In some method to create an instance of ClassName
    var factory = container.Resolve<ClassName.Factory>();
    var instance = factory.Invoke(obj1Instance, "text");
    

    编辑:

    我自己运行后遇到了同样的异常,但很快意识到问题所在。引用autofac's entry on delegate factories我看到了这个:

    Autofac默认将delegate的参数与构造函数的参数按名称匹配

    我的构造函数参数的名称和我的委托参数的名称不匹配,这导致autofac 尝试按类型解析对象,因为你没有(除非你知道你想这样做,否则不应该这样做,即便如此,您也不应该)注册 string autofacAutofac.Core.Activators.Reflection.DefaultConstructorFinder 失败。

    【讨论】:

    • 不,即使删除行 container.RegisterType(); 我仍然面临同样的异常还有什么我在这里想念的吗?
    • 如果我删除该行,看到此异常是准确的:请求的服务'ClassName+Factory'尚未注册
    • 但如上例所示,我为委托和构造函数使用相同的参数名称。
    • 是的,我知道,但我认为——基于提到具有objectint 的构造函数的异常,并且这些类型名称显然不属于任何代码库——提取您在此问题中发布的代码是修改代码以将其发布到堆栈溢出的结果,您可能在此过程中已部分修复。
    猜你喜欢
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多