开发者

Dependency Injection - The name 'Bind' does not exist in the current context - MethodAccessException was unhandled

开发者 https://www.devze.com 2023-03-09 03:12 出处:网络
Code Sample: namespace DependencyInjection { class Program { static void Main(string[] args) { IKernel kernel = new StandardKernel();

Code Sample:

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)开发者_StackOverflow社区
    {
        Console.WriteLine("Arrow - ", target);
    }
}
}

This is my first attempt to implement DI using ninject.

I am not sure how to resolve the error "The name 'Bind' does not exist in the current context". I went through this question Compilation Error with Ninject but still not sure how to solve this. How can this be resolved. It will be great if I can get the code sample so that I can understand much better

Edit :

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);
    }
}
}

The above code results in "MethodAccessException was unhandled" on line var samurai = kernel.Get(); I search Google but was not able to find any concrete solution

Exception

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: 


The reason why you are getting this error is because Bind is normally a method on the kernel, so you should do this outside the module. Also you should create your bindings before resolving Samurai, so swap the last two lines around:

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

}

The reason why Bind sometimes works without kernel is because you probably saw tutorials doing that inside a module. NinjectModule has a protected Bind method that performs the same function:

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

Either method is appropriate, when your bindings get a bit complex, it's advisable to put them into modules.

EDIT Make sure all of your classes and interfaces are public, otherwise Ninject can't execute them. When accessibility modifier is not specified, it defaults to internal. This explains MethodAccessException.


kernel.Bind<IWeapon>().To<Sword>();

or do the binding in a class that inherits from NinjectModule.


The Bind() method is define on IBindingRoot. Both StandardKernel and NinjectModule derives from BindingRoot which implements IBindingRoot.

You can bind your services on the kernel

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>();
}

or by using a Ninject module

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();
    }
}

and then load the module

public static void Main()
{
    var module = new WeaponModule();
    var kernel = new StandardKernel(module);
    var weapon = kernel.Get<IWeapon>();
}
0

精彩评论

暂无评论...
验证码 换一张
取 消