Asp.net mvc 如何禁用或防止Autofac踢入不需要的位置?

Asp.net mvc 如何禁用或防止Autofac踢入不需要的位置?,asp.net-mvc,autofac,Asp.net Mvc,Autofac,我有一个带有默认构造函数和DI构造函数的控制器: #if PROTOTYPING public class MyPrototypeController : Controller { MyRandomDataGeneratorComponent generatorSeededTheWayINeed; public MyPrototypeController() : this(new MyRandomDataGeneratorComponent(DateTime.No

我有一个带有默认构造函数和DI构造函数的控制器:

#if PROTOTYPING
public class MyPrototypeController : Controller
{
    MyRandomDataGeneratorComponent generatorSeededTheWayINeed;
    public MyPrototypeController()
        : this(new MyRandomDataGeneratorComponent(DateTime.Now.Millisecond)
        /* whatever seed, I don't care */) {
    }
    public MyPrototypeController(MyRandomDataGeneratorComponent generatorSeededTheWayINeed) {
        /* DI for testing purposes, I need to be able to reproduce the same random situation */
        this.generatorSeededTheWayINeed = generatorSeededTheWayINeed;
    }
}
public class MyRandomDataGeneratorComponent
{
    public MyRandomDataGeneratorComponent(Int32 randomSeed)
    {
        /* use the seed to initialized the random generator */
    }
}
#endif
containerBuilder.Register(c => new MyController())
    .AsSelf();
我希望通过调用默认构造函数来创建控制器。然而,Autofac认为它非常聪明,它竭尽全力使用参数化构造函数,但它无法创建MyRandomDataGeneratorComponent,因为它无法解析数字

天知道这有多烦人


我如何告诉此框架使用默认构造函数,或者完全禁用此控制器的默认构造函数?

Autofac选择它知道如何解决的依赖关系最多的构造函数。似乎注册了
MyComponent
,但注册不正确:您没有指定
someNumber
应该是什么。换句话说,如果您只是尝试
Resolve()
您也会遇到同样的问题-
MyController
不是这里的根本问题

有几种方法可以解决这个问题。最简单的方法是向MyComponent添加默认构造函数

public MyComponent() : this(DateTime.Now.Millisecond) { }
第二个最简单的方法是调整
MyComponent
注册

containerBuilder.Register(c => new MyComponent(DateTime.Now.Milliseconds))
    .AsSelf();
您也可以这样编写注册,以显式使用默认构造函数:

#if PROTOTYPING
public class MyPrototypeController : Controller
{
    MyRandomDataGeneratorComponent generatorSeededTheWayINeed;
    public MyPrototypeController()
        : this(new MyRandomDataGeneratorComponent(DateTime.Now.Millisecond)
        /* whatever seed, I don't care */) {
    }
    public MyPrototypeController(MyRandomDataGeneratorComponent generatorSeededTheWayINeed) {
        /* DI for testing purposes, I need to be able to reproduce the same random situation */
        this.generatorSeededTheWayINeed = generatorSeededTheWayINeed;
    }
}
public class MyRandomDataGeneratorComponent
{
    public MyRandomDataGeneratorComponent(Int32 randomSeed)
    {
        /* use the seed to initialized the random generator */
    }
}
#endif
containerBuilder.Register(c => new MyController())
    .AsSelf();
您还可以更改代码,使
MyComponent
根本不向Autofac注册,然后Autofac将不会选择
MyController(MyComponent组件)
构造函数,但这似乎不是最佳解决方案

编辑

这些测试表明,
MyRandomDataGeneratorComponent
(又称
MyComponent
)实际上已注册。如果您需要帮助了解它是如何注册的,请发布您的注册码

public class MyController
{
    MyRandomDataGeneratorComponent generatorSeededTheWayINeed;
    public MyController()
        : this(new MyRandomDataGeneratorComponent(DateTime.Now.Millisecond)
            /* whatever seed, I don't care */)
    {
    }
    public MyController(MyRandomDataGeneratorComponent generatorSeededTheWayINeed)
    {
        /* DI for testing purposes, I need to be able to reproduce the same random situation */
        this.generatorSeededTheWayINeed = generatorSeededTheWayINeed;
    }
}
public class MyRandomDataGeneratorComponent
{
    public MyRandomDataGeneratorComponent(Int32 randomSeed)
    {
        /* use the seed to initialized the random generator */
    }
}

[TestMethod]
public void example1()
{
    var cb = new ContainerBuilder();
    cb.RegisterType<MyController>().AsSelf();
    var container = cb.Build();

    Assert.IsFalse(container.IsRegistered<MyRandomDataGeneratorComponent>());
    // since MyRandomDataGeneratorComponent is not registered,
    // the default constructor is used
    var instance = container.Resolve<MyController>();
}

[TestMethod]
[ExpectedException(typeof(Autofac.Core.DependencyResolutionException))]
public void example2()
{
    var cb = new ContainerBuilder();
    cb.RegisterType<MyController>().AsSelf();
    cb.RegisterType<MyRandomDataGeneratorComponent>().AsSelf();
    var container = cb.Build();

    Assert.IsTrue(container.IsRegistered<MyRandomDataGeneratorComponent>());
    // since MyRandomDataGeneratorComponent is registered, Autofac
    // uses that constructor, but cannot resolve parameter "randomSeed"
    try
    {
        var instance = container.Resolve<MyController>();
    }
    catch (Autofac.Core.DependencyResolutionException ex)
    {
        Assert.IsTrue(ex.Message.Contains(
            "Cannot resolve parameter 'Int32 randomSeed'"));
        throw;
    }
}
公共类MyController
{
MyRandomDataGenerator组件生成器需要每日更新;
公共MyController()
:此(新的MyRandomDataGeneratorComponent(DateTime.Now.毫秒)
/*不管是什么种子,我都不在乎*/)
{
}
公共MyController(MyRandomDataGenerator组件生成器需要每日更新)
{
/*为了测试的目的,我需要能够重现相同的随机情况*/
this.generatorseedthewayineed=generatorseedthewayineed;
}
}
公共类MyRandomDataGeneratorComponent
{
公共MyRandomDataGeneratorComponent(Int32 randomSeed)
{
/*使用种子初始化随机生成器*/
}
}
[测试方法]
公共无效示例1()
{
var cb=新的ContainerBuilder();
cb.RegisterType().AsSelf();
var container=cb.Build();
Assert.IsFalse(container.IsRegistered());
//由于MyRandomDataGeneratorComponent未注册,
//使用默认构造函数
var instance=container.Resolve();
}
[测试方法]
[ExpectedException(类型(Autofac.Core.DependencyResolutionException))]
公共无效示例2()
{
var cb=新的ContainerBuilder();
cb.RegisterType().AsSelf();
cb.RegisterType().AsSelf();
var container=cb.Build();
Assert.IsTrue(container.IsRegistered());
//由于MyRandomDataGeneratorComponent已注册,Autofac
//使用该构造函数,但无法解析参数“randomSeed”
尝试
{
var instance=container.Resolve();
}
捕获(Autofac.Core.dependencResolutionException ex)
{
Assert.IsTrue(例如Message.Contains(
“无法解析参数'Int32 randomSeed'”);
投
}
}

他们在上面回答了nemesv给你的答案:

Register(c=>newmycontroller()).AsSelf();是Autofac中的“切换到手动模式”。使用它,它将在不更改类的情况下工作


.AsSelf()是您需要的。

MyComponent未在Autofac注册。请不要建议我更改类以使Autofac正常工作。我确信这是一个必须围绕我的需求的框架,而不是相反。无法关闭或切换到手动模式表明框架设计不当。@bonomo第三个示例:
vontainerBuilder.Register(c=>new MyController()).AsSelf()是Autofac中的“切换到手动模式”。如果异常显示“无法解析MyComponent的参数'someNumber',则MyComponent已注册。(否则异常会说“MyComponent未注册”)也许您正在使用“任何尚未注册的具体类型”源?我发誓MyComponent未注册。这就是我添加默认构造函数的原因,因为我不想麻烦注册,我希望使用默认构造函数创建控制器不会有问题,即使组件没有注册。问题是,组件是一个临时的东西,只用于开发目的(模拟),它将离开生产代码。这就是为什么我希望它尽可能少地参与,仍然能够为测试目的注入它?这是一个。如果Autofac尝试创建MyComponent,则表示MyComponent已在您的容器中注册。你的评论表明情况并非如此。您的场景的真实状态是什么?如果该组件不在您的容器中,我相信Autofac会选择默认构造函数,因为它不“知道”MyComponent。@Steven,我添加了默认构造函数,因为我不想麻烦注册,我希望使用默认构造函数,即使组件没有注册,创建控制器也不会有问题。问题是,组件是一个临时的东西,只用于开发目的(模拟),它将离开生产代码。这就是为什么我希望它尽可能少地参与,仍然能够将它注入到