Внедрение зависимостей - имя «Bind» не существует в текущем контексте - исключение MethodAccessException не обработано - PullRequest
3 голосов
/ 28 мая 2011

Пример кода:

namespace DependencyInjection
{
class Program  
{
    static void Main(string[] args)
    {
        IKernel kernel = new StandardKernel();
        var samurai = kernel.Get<Samurai>();
        Bind<IWeapon>().To<Sword>();
   }       
}



class Samurai
{
    readonly IWeapon _weapon;
    public Samurai(IWeapon weapon)
    {
        _weapon = weapon;
    }
    public void Attack(string target)
    {
        _weapon.Hit(target);
    }
}

interface IWeapon
{
    void Hit(string target);
}

class Sword : IWeapon
{
    public void Hit(string target)
    {
        Console.WriteLine("Sword - ", target);
    }
}

class Arrow : IWeapon
{
    public void Hit(string target)
    {
        Console.WriteLine("Arrow - ", target);
    }
}
}

Это моя первая попытка реализовать DI с помощью ninject.

Я не уверен, как устранить ошибку «Имя« Bind »не существует в текущем контексте». Я прошел этот вопрос Ошибка компиляции с Ninject , но все еще не уверен, как решить эту проблему. Как это можно решить. Было бы здорово, если бы я мог получить пример кода, чтобы я мог лучше понять

Редактировать:

namespace DependencyInjection
{
class Program  
{
    static void Main(string[] args)
    {
        IKernel kernel = new StandardKernel();
        kernel.Bind<IWeapon>().To<Sword>();
        var samurai = kernel.Get<Samurai>(); -----> Exception Line
        samurai.Attack("Hello");
   }       
}

class Samurai
{
    readonly IWeapon _weapon;
    public Samurai(IWeapon weapon)
    {
        _weapon = weapon;
    }
    public void Attack(string target)
    {
        _weapon.Hit(target);
    }
}

interface IWeapon
{
    void Hit(string target);
}

class Sword : IWeapon
{
    public void Hit(string target)
    {
        Console.WriteLine("Sword - ", target);
    }
}

class Arrow : IWeapon
{
    public void Hit(string target)
    {
        Console.WriteLine("Arrow - ", target);
    }
}
}

Приведенный выше код приводит к тому, что «MethodAccessException не обработано» в строке var samurai = kernel.Get (); Я ищу в Google, но не смог найти никакого конкретного решения

Исключение

System.MethodAccessException was unhandled
  Message="DependencyInjection.Sword..ctor()"
  Source="Anonymously Hosted DynamicMethods Assembly"
  StackTrace:
       at DynamicInjector84db385a6cfb4301b146100b5027c44a(Object[] )
       at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
       at Ninject.Activation.Context.Resolve()
       at Ninject.KernelBase.<Resolve>b__4(IContext context)
       at System.Linq.Enumerable.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x)
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
       at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
       at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
       at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass1.<Create>b__0(ITarget target)
       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)
       at Ninject.Activation.Context.Resolve()
       at Ninject.KernelBase.<Resolve>b__4(IContext context)
       at System.Linq.Enumerable.<>c__DisplayClass12`3.<CombineSelectors>b__11(TSource x)
       at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
       at System.Linq.Enumerable.<CastIterator>d__aa`1.MoveNext()
       at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
       at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[] parameters)
       at DependencyInjection.Program.Main(String[] args) in D:\Sandboxes\C_Sharp\DependencyInjection\DependencyInjection\Program.cs:line 18
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

Ответы [ 3 ]

6 голосов
/ 28 мая 2011

Причина, по которой вы получаете эту ошибку, заключается в том, что Bind обычно является методом в ядре, поэтому вы должны делать это вне модуля.Также вы должны создать свои привязки перед разрешением Самурая, поэтому поменяйте местами последние две строки:

static void Main(string[] args)
{
    IKernel kernel = new StandardKernel();
    kernel.Bind<IWeapon>().To<Sword>();
    kernel.Bind<Samurai>().ToSelf();
    var samurai = kernel.Get<Samurai>();

}

Причина, по которой Bind иногда работает без ядра, заключается в том, что вы, вероятно, видели учебные пособияделать это внутри модуля.NinjectModule имеет защищенный метод Bind, который выполняет ту же функцию:

public class NinjaModule : NinjectModule {
    public void Load() {
       Bind<Samurai>().ToSelf()
       Bind<IWeapon>().To<Sword>();
    }
} 

Любой метод подходит, когда ваши привязки становятся немного сложными, желательно поместить их в модули.

РЕДАКТИРОВАТЬ Убедитесь, что все ваши классы и интерфейсы общедоступны, в противном случае Ninject не сможет их выполнить.Если модификатор доступности не указан, по умолчанию используется значение internal.Это объясняет MethodAccessException.

1 голос
/ 28 мая 2011

Метод Bind () определен для IBindingRoot . И StandardKernel и NinjectModule являются производными от BindingRoot , который реализует IBindingRoot.

Вы можете привязать свои сервисы к ядру

public static void Main()
{
    var kernel = new StandardKernel();
    kernel.Bind<IWeapon>().To<Sword>();
    // Optional, Ninject will try to resolve any non-registered concrete type.
    kernel.Bind<Samuari>().ToSelf();

    var samurai = kernel.Get<Samuari>();
}

или с помощью модуля Ninject

public class WeaponModule : NinjectModule
{
    public override void Load()
    {
        Bind<IWeapon>().To<Sword>();
        // Optional, Ninject will try to resolve any non-registered concrete type.
        Bind<Samuari>().ToSelf();
    }
}

и затем загрузить модуль

public static void Main()
{
    var module = new WeaponModule();
    var kernel = new StandardKernel(module);
    var weapon = kernel.Get<IWeapon>();
}
1 голос
/ 28 мая 2011
kernel.Bind<IWeapon>().To<Sword>();

или выполните привязку в классе, который наследуется от NinjectModule.

...