代码示例:
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);
}
}
}
这是我第一次尝试使用ninject实现DI。
我不知道如何解决错误“当前上下文中不存在名称'Bind'”。我经历了这个问题Compilation Error with 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);
}
}
}
上面的代码导致行var“samurai = kernel.Get();行上的”MethodAccessException未处理“;我搜索谷歌但无法找到任何具体的解决方案
异常
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:
答案 0 :(得分:6)
您收到此错误的原因是因为Bind
通常是内核上的一个方法,因此您应该在模块外部执行此操作。你也应该在解决Samurai之前创建你的绑定,所以交换最后两行:
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 :(得分:1)
kernel.Bind<IWeapon>().To<Sword>();
或在继承自NinjectModule
。
答案 2 :(得分:1)
Bind()方法在IBindingRoot上定义。 StandardKernel和NinjectModule都来自实现IBindingRoot的BindingRoot。
您可以在内核上绑定服务
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>();
}