Итак, после многократного прикручивания я наконец получил Ninject, подключенный и компилирующийся в моем приложении MVC4. Проблема, с которой я столкнулся, - это интерфейс IDependencyScope, который больше не существует из того, что я могу сказать, и пространство имен System.Web.Http.Dependencies было устранено.
Итак, теперь моя проблема заключается в том, что у меня все подключено и после запуска приложения я получаю:
Sequence contains no elements
[InvalidOperationException: Sequence contains no elements]
System.Linq.Enumerable.Single(IEnumerable`1 source) +379
Ninject.Web.Mvc.NinjectMvcHttpApplicationPlugin.Start() in c:\Projects\Ninject\ninject.web.mvc\mvc3\src\Ninject.Web.Mvc\NinjectMvcHttpApplicationPlugin.cs:53
Ninject.Web.Common.Bootstrapper.<Initialize>b__0(INinjectHttpApplicationPlugin c) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:52
Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map(IEnumerable`1 series, Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:31
Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback) in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\Bootstrapper.cs:53
Ninject.Web.Common.NinjectHttpApplication.Application_Start() in c:\Projects\Ninject\Ninject.Web.Common\src\Ninject.Web.Common\NinjectHttpApplication.cs:81
Который я не смог отследить или даже начать понимать, откуда он.
Мои стандартные методы Ninject внутри Global.asax.cs выглядят следующим образом:
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind<IRenderHelper>().To<RenderHelper>();
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
return kernel;
}
protected override void OnApplicationStarted()
{
base.OnApplicationStarted();
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
}
И мой пользовательский резольвер:
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IKernel _kernel;
public NinjectDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _kernel.GetAll(serviceType);
}
catch (Exception)
{
return new List<object>();
}
}
public void Dispose()
{
// When BeginScope returns 'this', the Dispose method must be a no-op.
}
}
Любое понимание здесь было бы весьма признательным. Я потратил слишком много времени, пытаясь заставить любую инфраструктуру DI подключиться к последнему MVC4 RC, работающему на .NET 4.5, и теперь только что достиг уровня допуска, поскольку вещи просто не работают вообще.
Изменить # 1 Немного дальнейших исследований, копающихся в github, ExtensionsForIEnumerableOfT.cs не очень помогает:
И, возможно, если бы я сам написал это, я бы начал понимать это, но Bootstrapper.cs тоже не слишком помогает.
https://github.com/ninject/Ninject.Web.Common/blob/master/src/Ninject.Web.Common/Bootstrapper.cs
Надеясь, что эти подробности облегчат вам любого из вас, у кого может быть больше опыта с Ninject.
Изменить # 2 Произошла ошибка, особенно в NinjectMvcHttpApplicationPlugin.cs:
Строка нарушения:
ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
Что живет в следующем методе:
public void Start()
{
ModelValidatorProviders.Providers.Remove(ModelValidatorProviders.Providers.OfType<DataAnnotationsModelValidatorProvider>().Single());
DependencyResolver.SetResolver(this.CreateDependencyResolver());
RemoveDefaultAttributeFilterProvider();
}
Коллекция ModelValidatorProviders содержит 2 элемента: {} System.Web.Mvc.DataErrorInfoModelValidatorProvider {System.Web.Mvc.ClientDataTypeModelValidatorProvider}
И он пытается удалить один экземпляр:
System.Web.Mvc.DataAnnotationsModelValidatorProvider
Который, по-видимому, не загружен в коллекцию ModelValidationProviders.Providers. Любые идеи отсюда?
Разрешение выше исключения и на следующий
Чтобы решить проблему в ModelValidatorProviders, мне пришлось вручную добавить объект, который он ожидал. Итак, теперь мой метод CreateKernel выглядит так:
protected override IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Load(Assembly.GetExecutingAssembly());
kernel.Bind<IRenderHelper>().To<RenderHelper>();
kernel.Unbind<IDocumentViewerAdapter>();
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel));
ModelValidatorProviders.Providers.Add(new DataAnnotationsModelValidatorProvider());
FilterProviders.Providers.Add(new FilterAttributeFilterProvider());
return kernel;
}
Теперь он запускается и попадает в настоящие кишки Ninject, но все еще имеет проблему, которая еще не имеет смысла:
Exception Details: Ninject.ActivationException: Error activating IntPtr
No matching bindings are available, and the type is not self-bindable.
Activation path:
3) Injection of dependency IntPtr into parameter method of constructor of type Func{IKernel}
2) Injection of dependency Func{IKernel} into parameter lazyKernel of constructor of type HttpApplicationInitializationHttpModule
1) Request for IHttpModule
Suggestions:
1) Ensure that you have defined a binding for IntPtr.
2) If the binding was defined in a module, ensure that the module has been loaded into the kernel.
3) Ensure you have not accidentally created more than one kernel.
4) If you are using constructor arguments, ensure that the parameter name matches the constructors parameter name.
5) If you are using automatic module loading, ensure the search path and filters are correct.