首页 新闻 会员 周边 捐助

【在线等】装配 Autofac 后 引发的问题。相当严重!

1
悬赏园豆:15 [已解决问题] 解决于 2014-02-24 13:59

在已有系统加入autofac,在没有回收程序池之前是没有问题的,可以正常执行。

一旦回收程序池后就会引发如下异常:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'xxx.PublicController' can be invoked with the available services and parameters:
Cannot resolve parameter 'xxx.IAction action' of constructor 'Void .ctor(xxx.IAction)'.

 

autofac的配置:

        private ContainerBuilder RegisterService ()
        {
            var builder = new ContainerBuilder();

            var baseType = typeof(IDependency);
            var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();
            var AllServices = assemblys
                .SelectMany(s => s.GetTypes())
                .Where(p => baseType.IsAssignableFrom(p) && p != baseType);

            builder.RegisterControllers(assemblys.ToArray());

            builder.RegisterAssemblyTypes(assemblys.ToArray())
                   .Where(t => baseType.IsAssignableFrom(t) && t != baseType)
                   .AsImplementedInterfaces().InstancePerLifetimeScope();

            return builder;
        }
Y2zz的主页 Y2zz | 菜鸟二级 | 园豆:393
提问于:2013-08-28 18:09
< >
分享
最佳答案
2

之前我说过,你的程序中

var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();

必须改成:

var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();

就可以了!!!

这个问题也困扰了我很久,希望能帮助到大家!

收获园豆:15
kxlsoft | 菜鸟二级 |园豆:217 | 2014-02-13 10:22

BuildManager 是从哪儿来的,这句话执行不成功啊

408580741 | 园豆:202 (菜鸟二级) | 2014-02-13 17:48

是否还是使用autofac或者是unity

408580741 | 园豆:202 (菜鸟二级) | 2014-02-13 17:51

已经知道了,没引用相关东西,谢谢了,可以啦

408580741 | 园豆:202 (菜鸟二级) | 2014-02-13 17:54

大神,厉害~这个问题,多年后的我也遇到了。谢谢大神的指点。也谢谢帖主的资源共享。祝你们身体健康,万事如意~

浮云的年代 | 园豆:200 (初学一级) | 2019-12-18 14:51
其他回答(7)
0

建议的根治方法:MVC Controller不使用构造函数依赖注入。

我们以前也遇到过类似问题,是在更新dll的时候。

如果你坚持用Controller的构造函数依赖注入,也有办法解决,但需要花些功夫研究。

 

dudu | 园豆:30939 (高人七级) | 2013-08-28 18:23

属性注入没找到具体方法,实际上我更倾向于用属性注入

之前用MEF侵入性太强。所以改用autofac来替换Mef

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2013-08-28 18:26

@Y叔: 这个问题与autofac无关

支持(0) 反对(0) dudu | 园豆:30939 (高人七级) | 2013-08-28 20:28

@Y叔: RegisterService()是在什么地方调用的?

支持(0) 反对(0) dudu | 园豆:30939 (高人七级) | 2013-08-28 20:29

@dudu: 在Application_Start最后调用的,其实我的目的比较简单,不想用代码去配置,也不想写xml配置。目前是注册程序集内所有继承IDependency的接口

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2013-08-28 20:43

@Y叔: 在Application_Start调用会有问题,要更早一些,我们是这样调用的:

[assembly: PreApplicationStartMethod(typeof(BootStrapper.Initializer), "Initialize")]
支持(0) 反对(0) dudu | 园豆:30939 (高人七级) | 2013-08-28 20:49

@dudu: 我已经按照刚刚你说的方式试了,问题依旧。

AssemblyInfo.cs:

[assembly: PreApplicationStartMethod(typeof(BootStrapper), "Initializer")]

 

public static class BootStrapper
    {
        public static void Initializer ()
        {
            DependencyResolver.SetResolver(new AutofacDependencyResolver(RegisterService().Build()));
        }

        /// <summary>
        /// 注册服务
        /// </summary>
        /// <returns></returns>
        private static ContainerBuilder RegisterService ()
        {
            var builder = new ContainerBuilder();

            var baseType = typeof(IDependency);
            var assemblys = AppDomain.CurrentDomain.GetAssemblies().ToList();
            var AllServices = assemblys
                .SelectMany(s => s.GetTypes())
                .Where(p => baseType.IsAssignableFrom(p) && p != baseType);

            builder.RegisterControllers(assemblys.ToArray()).PropertiesAutowired();

            builder.RegisterAssemblyTypes(assemblys.ToArray())
                   .Where(t => baseType.IsAssignableFrom(t) && t != baseType)
                   .PropertiesAutowired().AsImplementedInterfaces().InstancePerLifetimeScope();

            return builder;
        }
    }
支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2013-08-28 20:59

@Y叔: 我这边暂时也没有好的解决方法,我们现在也不用DependencyResolver.SetResolver了,Controller的构造函数依赖注入很容易造成滥用。

支持(0) 反对(0) dudu | 园豆:30939 (高人七级) | 2013-08-28 21:36

@dudu: 谢谢

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2013-08-28 21:38

你好,如果用构造函数,怎么可以解决这个问题?

支持(0) 反对(0) jimcsharp | 园豆:244 (菜鸟二级) | 2015-02-24 09:46
0

 

 

 

 

我是Google代理:

http://stackoverflow.com/questions/16006248/none-of-the-constructors-found-with-autofac-core-activators-reflection-defaultc

 

另外:

1。 DependencyResolver 是否是Static

2。Inintalize()时,DependencyResolver 是否有方法可以清空原来的的Resolver.

3. Application_start()是没有问题的,虽然我用的不是AotuConf

4.建议换Ninject, 我熟一些。 :)

5。 Bootstrapper本身不需要static

 

 

 

 

予沁安 | 园豆:214 (菜鸟二级) | 2013-08-29 00:51
3

如果你是web程序请使用下面方式获取assembly。

var assemblys = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList();

漫步码园 | 园豆:202 (菜鸟二级) | 2013-12-31 09:44
0

你解决没有,如果解决了加我QQ告诉我下,408580741

408580741 | 园豆:202 (菜鸟二级) | 2014-02-12 16:34

用autoface没解决,改用 Unity了

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2014-02-12 16:52

@Y叔: 是在是郁闷啊,用unity的变化大不大

支持(0) 反对(0) 408580741 | 园豆:202 (菜鸟二级) | 2014-02-12 17:08

@408580741: 用的配置文件的方式,都差不多

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2014-02-12 17:10

@Y叔: 也能像上面一样让其继承一个接口,然后所有继承这个接口的类都注册吗

支持(0) 反对(0) 408580741 | 园豆:202 (菜鸟二级) | 2014-02-13 00:04

@408580741: 是的,是一样的

支持(0) 反对(0) 408580741 | 园豆:202 (菜鸟二级) | 2014-04-01 00:53
0

我刚才也遇到了相同问题,其实这个问题是与autofac无关的。别错怪它了,我一步步排查之后,发现原来是我的业务接口,在实现的时候忘记继承接口了(太大意),也就是你所注入的接口定义,没有一个相关的实现,所以报了这错,只要有相关的实现类,则错误自动消除。

寒_飞 | 园豆:204 (菜鸟二级) | 2015-01-20 15:33

这个可以确认不是忘记继承,是回收程序池后导致的报错

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2015-01-20 16:23

@Y2zz: 我刚才报的错和你的一模一样,百度了下也无果,就看到这篇帖子,但是说的是无解,于是我仔细检测了一次发现了这个低级错误,但是线程池回收的时候是否会报错,目前不清楚。

支持(0) 反对(0) 寒_飞 | 园豆:204 (菜鸟二级) | 2015-01-20 16:28

@寒_飞: 如果没继承 访问直接报错了,没有回收的事了,我遇到的情况是回收之前访问正常,回收后就报错

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2015-01-20 16:29

@Y2zz: 实现类不继承业务契约接口是不会报错的。因为它只是一个单独的类,而和业务接口并没有任何联系,而在MVC里通过构造函数注入的时候注册的是一个业务契约接口,报错就报错在Autofac去自动创建对象的时候,错误代码与楼主的也完全一模一样,而我修复了这个低级错误之后,autofac立刻正常使用了,所以目前看来肯定还是和程序本身有着关系,并不认为是autofac的错误。

支持(0) 反对(0) 寒_飞 | 园豆:204 (菜鸟二级) | 2015-01-20 16:37

我的业务类继承了接口,还是报这个错误。

支持(0) 反对(0) jimcsharp | 园豆:244 (菜鸟二级) | 2015-02-24 09:44
0

你好,请问怎么解决的?能麻烦发下嘛?我也遇到了这个问题。

猿进化 | 园豆:174 (初学一级) | 2015-12-28 19:14

很蛋疼,用autoface没解决,改用 Unity了

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2015-12-28 19:30

@Y2zz:请问用autoface改进不了么?我的是运行第一次能通过,接着运行第二次就需要先重新编译才能通过

支持(0) 反对(0) 猿进化 | 园豆:174 (初学一级) | 2015-12-28 19:38

@猿进化: 你的情况应该跟我一样

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2015-12-28 19:43

@Y2zz: 看来这个问题只能交给我师父解决了。等有结果了我到时告诉你。

支持(0) 反对(0) 猿进化 | 园豆:174 (初学一级) | 2015-12-28 19:47

@猿进化: 好的,谢谢

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2015-12-28 20:41

@Y2zz: 目前,我师父给出的解决方法是替替换默认控制器工厂

支持(0) 反对(0) 猿进化 | 园豆:174 (初学一级) | 2015-12-30 08:35

@Y2zz: 就是配置起来比较麻烦

<autofac>
    <components>
      <component type="MyBlog.Factory.DbSession,MyBlog.Factory"/>
      <component type="MyBlog.BLL.CategoryManager,MyBlog.BLL" service="MyBlog.IBLL.ICategoryManager,MyBlog.IBLL"/>
      <component type="MyBlog.UI.Controllers.CategoryController,MyBlog.UI"/>
    ......

</components>
  </autofac>

支持(0) 反对(0) 猿进化 | 园豆:174 (初学一级) | 2015-12-30 08:39
0

我刚刚也是遇到这个问题,我是这么解决的,我的Repository注入时,没有使用接口

原始

  private readonly BusoppinformationRepository _busoppinformationService;
        public BusoppinformationService(BusoppinformationRepository busoppinformationRepository)
        {
            _busoppinformationService = busoppinformationRepository;
        }

正确

        private readonly IBusoppinformationRepository _busoppinformationService;
        public BusoppinformationService(IBusoppinformationRepository busoppinformationRepository)
        {
            _busoppinformationService = busoppinformationRepository;
        }

 

 

SeeThrough | 园豆:189 (初学一级) | 2016-07-27 22:53

我当时并不是这个原因

支持(0) 反对(0) Y2zz | 园豆:393 (菜鸟二级) | 2016-07-28 00:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册