Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Autofac.Core.DependencyResolutionException使用自定义配置文件配置AutoMapper时_C#_Asp.net Mvc 5_Owin_Automapper_Autofac - Fatal编程技术网

C# Autofac.Core.DependencyResolutionException使用自定义配置文件配置AutoMapper时

C# Autofac.Core.DependencyResolutionException使用自定义配置文件配置AutoMapper时,c#,asp.net-mvc-5,owin,automapper,autofac,C#,Asp.net Mvc 5,Owin,Automapper,Autofac,我正在使用Autofac 4.3、Autofac.Owin 4、Autofac.MVC5 4、Autofac.MVC5.Owin 4、Autofac.MVC5.Owin 4和AutoMapper 5.2配置AutoMapper,以将域对象从/映射到Asp.Net MVC5应用程序中的视图模型对象 我确实决定为每个域实体创建一个AutoMapper配置文件,如下图所示,只留下没有参数的构造函数,因为我想设置配置文件的名称 注意:此代码位于程序集A中 public partial class Doc

我正在使用Autofac 4.3、Autofac.Owin 4、Autofac.MVC5 4、Autofac.MVC5.Owin 4、Autofac.MVC5.Owin 4和AutoMapper 5.2配置AutoMapper,以将域对象从/映射到Asp.Net MVC5应用程序中的视图模型对象

我确实决定为每个域实体创建一个AutoMapper配置文件,如下图所示,只留下没有参数的构造函数,因为我想设置配置文件的名称

注意:此代码位于程序集A中

public partial class DoctorsMappingProfile : Profile
{
    #region Constructors

    public DoctorsMappingProfile() : base(typeof(DoctorsMappingProfile).FullName)
    {
        // Code of mapping removed because it is not part of the problem
    }

    #endregion Constructors
}
为了注册AutoMapper和我遵循的配置文件,用户mpetito很好地解释了这些配置文件,并说明它们是按照用户检查的方式工作的。我在Startup分部类中的代码如下:

注1:此代码位于引用程序集A的程序集B中

public partial class DoctorsMappingProfile : Profile
{
    #region Constructors

    public DoctorsMappingProfile() : base(typeof(DoctorsMappingProfile).FullName)
    {
        // Code of mapping removed because it is not part of the problem
    }

    #endregion Constructors
}
注2:我对已注册的程序集执行程序集扫描,然后将扫描的程序集数组作为参数传递给ContainerBuilder的方法RegisterAssemblyTypes

    public partial class Startup
{
    #region Methods

    public void ConfigureAutoFacContainer(IAppBuilder app)
    {

        var builder = new ContainerBuilder();
        builder.RegisterControllers(typeof(MvcApplication).Assembly); 
        builder.RegisterFilterProvider(); 
        builder.RegisterSource(new ViewRegistrationSource());
        // TODO: Logger!                        
        var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();         
        this.ConfigureAutoMapper(builder, assemblies);
        // TODO: Modules!
        var container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));                       
        app.UseAutofacMiddleware(container);
        app.UseAutofacMvc();
    }

    private void ConfigureAutoMapper(ContainerBuilder builder, Assembly[] registeredAssemblies)
    {
        //register your profiles, or skip this if you don't want them in your container
        builder.RegisterAssemblyTypes(registeredAssemblies).AssignableTo(typeof(Profile)).As<Profile>(); //.UsingConstructor(typeof(string));

        //register your configuration as a single instance
        builder.Register(ctx => new MapperConfiguration(cfg =>
        {
            //add your profiles (either resolve from container or however else you acquire them)
            foreach (var profile in ctx.Resolve<IEnumerable<Profile>>())
            {
                cfg.AddProfile(profile);
            }
        })).AsSelf().SingleInstance();

        //register your mapper
        builder.Register(ctx => ctx.Resolve<MapperConfiguration>()
            .CreateMapper(ctx.Resolve))
            .As<IMapper>()
            .InstancePerLifetimeScope();
    }

    #endregion Methods
}
注意:此代码位于程序集A中

public partial class DoctorsMappingProfile : G2AutoMapperProfile //Profile
{
    #region Constructors

    public DoctorsMappingProfile() : base(typeof(DoctorsMappingProfile).FullName)
    {
        //removed because it is not part of the problem
    }

    #endregion Constructors
}
最后,这是程序集B中的ConfigureAutoMapper代码,它可以工作:

private void ConfigureAutoMapper(ContainerBuilder builder, Assembly[] registeredAssemblies)
    {
        //register your profiles, or skip this if you don't want them in your container
        builder.RegisterAssemblyTypes(registeredAssemblies).AssignableTo(typeof(G2AutoMapperProfile)).As<G2AutoMapperProfile>();

        //register your configuration as a single instance
        builder.Register(ctx => new MapperConfiguration(cfg =>
        {
            //add your profiles (either resolve from container or however else you acquire them)
            foreach (var profile in ctx.Resolve<IEnumerable<G2AutoMapperProfile>>())
            {
                cfg.AddProfile(profile);
            }
        })).AsSelf().SingleInstance();

        //register your mapper
        builder.Register(ctx => ctx.Resolve<MapperConfiguration>()
            .CreateMapper(ctx.Resolve))
            .As<IMapper>()
            .InstancePerLifetimeScope();
    }
private void ConfigureAutoMapper(ContainerBuilder生成器,程序集[]注册表程序集)
{
//注册您的配置文件,如果您不想在容器中注册,请跳过此步骤
RegisterAssemblyTypes(registeredAssemblies).AssignableTo(typeof(G2AutoMapperProfile)).As();
//将配置注册为单个实例
builder.Register(ctx=>newmapperconfiguration(cfg=>
{
//添加您的配置文件(从容器解析或以其他方式获取)
foreach(ctx.Resolve()中的变量配置文件)
{
cfg.AddProfile(profile);
}
})).AsSelf().SingleInstance();
//注册你的地图绘制者
builder.Register(ctx=>ctx.Resolve()
.CreateMapper(ctx.Resolve))
.As()
.InstancePerLifetimeScope();
}

。。。但是我仍然不明白为什么原始代码对我不起作用。

首先,您没有必要在
DoctorsMappingProfile
中显式调用
Profile
的受保护构造函数。原因是您传递的
profileName
是AutoMapper默认使用的,我们可以看到

另外,关于在Autofac容器中注册配置文件的第一种方法:

builder
.RegisterAssemblyTypes(注册表组件)
.可转让给(文件类型)
.As()
.使用构造函数(类型(字符串));
这意味着您明确要求Autofac使用构造函数创建
概要文件
类的实例,该构造函数只有一个
字符串类型的参数。问题是Autofac不知道它必须在构造函数中使用什么
string

这也是错误的,因为您创建了一个无参数构造函数,该构造函数反过来调用参数化构造函数

我不确定使用无参数构造函数调用
会有什么作用,但我认为,最好让Autofac为您选择最好的构造函数,尤其是当defaut参数较少的构造函数是您希望它使用的构造函数时

通过查看您提供的解决方案/解决方案,我的感觉得到了加强。你有效地做到了:

  • 创建一个基类,该基类完全模仿
    Profile
    的特性,即默认的无参数构造函数和接受
    字符串的构造函数
  • 通过不使用构造函数
    在Autofac容器中注册配置文件
因此,我非常确定:

  • 摆脱自定义基类
  • 让您的配置文件再次从
    Profile
    继承
  • 不使用构造函数注册您的配置文件

您应该很好。

首先,您不需要在
DoctorsMappingProfile
中显式调用
Profile
的受保护构造函数。原因是您传递的
profileName
是AutoMapper默认使用的,我们可以看到

另外,关于在Autofac容器中注册配置文件的第一种方法:

builder
.RegisterAssemblyTypes(注册表组件)
.可转让给(文件类型)
.As()
.使用构造函数(类型(字符串));
这意味着您明确要求Autofac使用构造函数创建
概要文件
类的实例,该构造函数只有一个
字符串类型的参数。问题是Autofac不知道它必须在构造函数中使用什么
string

这也是错误的,因为您创建了一个无参数构造函数,该构造函数反过来调用参数化构造函数

我不确定使用无参数构造函数调用
会有什么作用,但我认为,最好让Autofac为您选择最好的构造函数,尤其是当defaut参数较少的构造函数是您希望它使用的构造函数时

通过查看您提供的解决方案/解决方案,我的感觉得到了加强。你有效地做到了:

  • 创建一个基类,该基类完全模仿
    Profile
    的特性,即默认的无参数构造函数和接受
    字符串的构造函数
  • 通过不使用构造函数
    在Autofac容器中注册配置文件
因此,我非常确定:

  • 摆脱自定义基类
  • 让您的配置文件再次从
    Profile
    继承
  • 不使用构造函数注册您的配置文件

你应该没事。

我为我的错误感到抱歉。我更正了粘贴在原始帖子中的代码。我描述的问题没有使用.UsingConstructor(t
public abstract class G2AutoMapperProfile : Profile
{
    #region Constructors

    protected G2AutoMapperProfile()
    {
    }

    protected G2AutoMapperProfile(string profileName) : base(profileName)
    {
    }

    #endregion Constructors
}
public partial class DoctorsMappingProfile : G2AutoMapperProfile //Profile
{
    #region Constructors

    public DoctorsMappingProfile() : base(typeof(DoctorsMappingProfile).FullName)
    {
        //removed because it is not part of the problem
    }

    #endregion Constructors
}
private void ConfigureAutoMapper(ContainerBuilder builder, Assembly[] registeredAssemblies)
    {
        //register your profiles, or skip this if you don't want them in your container
        builder.RegisterAssemblyTypes(registeredAssemblies).AssignableTo(typeof(G2AutoMapperProfile)).As<G2AutoMapperProfile>();

        //register your configuration as a single instance
        builder.Register(ctx => new MapperConfiguration(cfg =>
        {
            //add your profiles (either resolve from container or however else you acquire them)
            foreach (var profile in ctx.Resolve<IEnumerable<G2AutoMapperProfile>>())
            {
                cfg.AddProfile(profile);
            }
        })).AsSelf().SingleInstance();

        //register your mapper
        builder.Register(ctx => ctx.Resolve<MapperConfiguration>()
            .CreateMapper(ctx.Resolve))
            .As<IMapper>()
            .InstancePerLifetimeScope();
    }