【问题标题】:Ninject.ActivationException was unhandled by user code用户代码未处理 Ninject.ActivationException
【发布时间】:2013-12-28 17:11:55
【问题描述】:

过去 2 天我一直在解决这个问题,我想做的是阻止创建 DisplayWeatherAstronomy 的实例,我以为昨晚在 Tadmas 的帮助下在另一个线程上解决了这个问题,但我遇到了Ninject 的问题。

所以我修改了我的代码并使用接口将我的类变成了一个抽象类,但我仍然遇到了 Ninject 的问题,我不知道如何修复它,即使该错误看起来很容易解释。

我的错误是:

Ninject.ActivationException was unhandled by user code
  HResult=-2146233088
  Message=Error activating IDisplayWeatherAstronomy using binding from IDisplayWeatherAstronomy to GetWeatherAstronomyData
No constructor was available to create an instance of the implementation type.

Activation path:
  2) Injection of dependency IDisplayWeatherAstronomy into parameter igwa of constructor of type WeatherController
  1) Request for WeatherController

Suggestions:
  1) Ensure that the implementation type has a public constructor.
  2) If you have implemented the Singleton pattern, use a binding with InSingletonScope() instead.

  Source=Ninject
  StackTrace:
       at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 82
       at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
       at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
       at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197
       at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165
       at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114
       at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
       at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
       at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
       at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
       at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
       at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
       at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
       at Ninject.Web.Mvc.NinjectDependencyResolver.GetService(Type serviceType) in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectDependencyResolver.cs:line 56
       at Castle.Proxies.Invocations.IDependencyResolver_GetService.InvokeMethodOnTarget()
       at Castle.DynamicProxy.AbstractInvocation.Proceed()
       at Glimpse.Core.Extensibility.CastleInvocationToAlternateMethodContextAdapter.Proceed()
       at Glimpse.Core.Extensions.AlternateMethodContextExtensions.TryProceedWithTimer(IAlternateMethodContext context, TimerResult& timerResult)
       at Glimpse.Core.Extensibility.AlternateMethod.NewImplementation(IAlternateMethodContext context)
       at Glimpse.Core.Extensibility.AlternateTypeToCastleInterceptorAdapter.Intercept(IInvocation invocation)
       at Castle.DynamicProxy.AbstractInvocation.Proceed()
       at Castle.Proxies.IDependencyResolverProxy.GetService(Type serviceType)
       at System.Web.Mvc.DefaultControllerFactory.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType)
  InnerException: 

代码:

public abstract class GetWeatherAstronomyData : IDisplayWeatherAstronomy
    {
        public class DisplayWeatherAstronomy
        {
            public string SunRise { get; internal set; }
            public string SunSet { get; internal set; }
            public string MoonRise { get; internal set; }
            public string MoonSet { get; internal set; }
        }

        public IEnumerable<DisplayWeatherAstronomy> WeatherAstronomy(string id)
        {
            var doc = WeatherForcast.WeatherLocationSearchXmlDataAsync(id);
            var result = XDocument.Parse(doc.Result);
            var displayAstronomy = (from wd in result.Descendants("astronomy")
                                    select new DisplayWeatherAstronomy
                                    {
                                        SunRise = (string)wd.Element("sunrise") ?? string.Empty,
                                        SunSet = (string)wd.Element("sunset") ?? string.Empty
                                    });

            return displayAstronomy;
        }
    }

界面

public interface IDisplayWeatherAstronomy
    {
        IEnumerable<GetWeatherAstronomyData.DisplayWeatherAstronomy> WeatherAstronomy(string id);
    }

忍者

private static void RegisterServices(IKernel kernel)
        {
            kernel.Bind<IDisplayWeatherAstronomy>()
                .To<GetWeatherAstronomyData>()
                .InSingletonScope();
        }  

最终控制器

private readonly IDisplayWeatherAstronomy _igwa;
        public WeatherController(IDisplayWeatherAstronomy igwa)
        {
            _igwa = igwa;
        } 

对于最终解决此问题的任何帮助将不胜感激

乔治

【问题讨论】:

    标签: c# asp.net-mvc-4 ninject


    【解决方案1】:

    如果您想防止您的类被其他人实例化,请将其与接口一起放在“额外”项目/程序集 B 中并使其成为 internal,而不是 public(不是 abstract , 任何一个!)。接口必须是public

    然后还向同一个程序集添加一个 ninject 模块,这会创建绑定:

    public class WeatherModule : NinjectModule
    {
      this.Bind<IDisplayWeatherAstronomy>().To<DisplayWeatherAstronomy>();
    }
    

    然后,在您的原始项目中,添加对项目/程序集 B 的引用并加载 WeatherModule

    kernel.Load<WeatherModule>();
    

    就是这样。

    但请记住,仍然任何人都可以通过使用来创建类

    IResolutionRoot.Get<IDisplayWeatherAstronomy>();
    

    所以只有当你可以限制对内核的访问时你才会有所收获,这通常是不切实际的。

    【讨论】:

    • 大家好,感谢您的回复,似乎给我的类一个内部的空构造函数解决了这个问题,因为我不能再在我的 MVC 控制器中创建该类的实例,但可以通过我的接口访问它
    【解决方案2】:

    您不能实例化抽象类。 Ninject 也做不到。从GetWeatherAstronomyData 中删除abstract 修饰符。

    【讨论】:

    • 嗨西蒙,我怎样才能防止创建 DisplayWeatherAstronomy 的实例,我已经尝试创建一个抽象类,使类内部化,但我没有做任何工作,我只是没有经验来解决这个问题
    • 我不明白您所说的“防止创建实例”是什么意思。为什么要阻止这种情况?
    • 嗨西蒙我只想通过接口调用类,我不想写或其他人写DisplayWeatherAstronomy gw = new DisplayWeatherAstronomy()等,基本上每个必须通过接口
    • @GeorgePhillipson 对象永远不能是抽象类的实例。正如 Simon 所说,它必须是一个具体的类才能让 Ninject 解决它。
    • Ninject 必须能够创建它。
    猜你喜欢
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多