【发布时间】:2010-10-25 23:06:49
【问题描述】:
很抱歉这个问题太长了,因为我整天都在研究这个问题。
一般问题:
我有一个包含以下项目的 ASP.Net MVC2 应用程序:MyApp.Web、MyApp.Services、MyApp.Data。
我们对接口进行编码并将 Ninject 2 用于 DI/IoC。
但是,我非常厌倦了打字(并且忘记打字):
Bind<ISomeService>.To<SomeService>;
因此,了解了 Ninject.Extensions.Convensions,我尝试使用它来自动扫描和注册模块以及 IXxxx => Xxxx 类型的简单依赖项。
我尝试过的方法有效(但还不够):
我可以使用以下代码来设置 Ninject,一切似乎都按预期连接起来了。
public static IKernel Initialize()
{
var kernel = new StandardKernel();
kernel.Scan(a => {
a.FromAssemblyContaining<MyApp.Data.SomeDataClass>();
a.FromAssemblyContaining<MyApp.Services.SomeServiceClass>();
a.AutoLoadModules();
a.BindWithDefaultConventions();
a.InTransientScope();
});
return kernel;
}
我想要完成的事情:
但是...我想以一种我认为受支持的方式进一步说明这一点,但我似乎无法让它发挥作用。
由于我们的 MyApp.Web 项目根本不使用任何(直接)来自 MyApp.Data 的内容,因此我试图避免引用 MyApp.Data。使用上面的代码,我必须从 MyApp.Web 中引用 MyApp.Data,因为编译时引用了 SomeDataClass。
我希望指定一个程序集的名称,以便 Ninject 扫描和注册。似乎 Conventions 扩展通过 From 重载支持这个,它接受一个字符串(或字符串的枚举)。
我尝试了什么以及它是如何破坏的:
所以,我尝试了 From 重载的几种变体:
public static IKernel Initialize()
{
var kernel = new StandardKernel();
kernel.Scan(a => {
a.From("MyApp.Data");
a.From("MyApp.Services.dll");
a.From("AnotherDependency, Version=1.0.0.0, PublicKeyToken=null"); //etc., etc. with the From(...)'s
a.AutoLoadModules();
a.BindWithDefaultConventions();
a.InTransientScope();
});
return kernel;
}
但我收到 FileNotFoundExceptions 并显示如下消息:
无法加载文件或程序集 'file:///C:\Program 文件 (x86)\通用文件\微软 Shared\DevServer\10.0\MyApp.Data' 或其依赖项之一。系统 找不到文件 指定。":"file:///C:\Program Files (x86)\通用文件\微软 共享\DevServer\10.0\
我发现自己试图解决这个问题:
我查看了 Ninject.Extensions.Conventions 的源代码,我承认我完全不知道它应该如何工作,但我可以看到它在做什么。
程序集扫描器会在我们调用各种 FromXXX 方法时建立要扫描的程序集列表。
当我调用 From("assemblyName") 方法时,它首先检查列表是否已经包含任何程序集,其中 assembly.AssemblyName.Name 等于我传入的名称(并且 AssemblyName.Name 是 simple 名称,即 MyApp.Data,根据 MSDN)。
Flow 通过几个不重要的方法,到达 FindAssemblies 方法。这个方法采用我传入的名称(我们已经看到应该是一个简单程序集名称)。然后它创建一个新的 AssemblyName,我们传入的名称用作 AssemblyName.CodeBase。
然后,它尝试将程序集加载到临时 AppDomain。这是上述异常失败的步骤。
显然,它搜索的路径是错误的,但我无法通过 From() 方法提供路径。这也不行。
我已经尝试了一些其他的 FromXXX 方法,但我一无所获,并且已经在这方面花费了太多时间。 FromAssembliesInPath 和 FromAssembliesMatching 也不起作用,因为它再次在完全错误的目录中搜索。
呃..又是什么问题:
谁能解释如何让 Ninject 约定按名称加载程序集,而不创建对程序集的引用并通过指定包含类型来加载它?请。
我已经搜索了Ninject google group 的页面和页面,并且我已经阅读了它的only (so it seems) relevant documentation 并且还没有能够解决它......但是。
【问题讨论】:
-
你在这个问题上做得很好。现在我会在邮件列表上交叉发布这个 - 那里有更多人使用不太主流的场景,他们并不都看这里......
标签: c# .net dependency-injection inversion-of-control ninject