我编写了一些C#类库,我想使用Ninject为我的类提供依赖注入。类库是否有可能声明一些代码(方法),这些代码(方法)将在加载类库时每次执行。我需要这个来为Ninject定义绑定。
答案 0 :(得分:6)
听起来你正在寻找相当于C ++的DllMain。在C#中无法做到这一点。
您能否提供一些有关您的场景的更多信息以及为什么需要在DllMain样式函数中执行代码?
在类型上定义静态构造函数不能解决此问题。静态类型构造函数仅保证在以任何方式使用类型本身之前运行。您可以定义一个静态构造函数,使用Dll中不访问该类型的其他代码,它的构造函数永远不会运行。
答案 1 :(得分:1)
您是否尝试过AppDomain.AssemblyLoad
活动?它在装载装配后发射。
AppDomain.CurrentDomain.AssemblyLoad += (s, e) =>
{
Assembly justLoaded = e.LoadedAssembly;
// ... etc.
};
答案 2 :(得分:1)
在过去的9个月里我使用了Ninject。听起来你需要做的是将你的库中存在的模块“加载”到Ninject内核中以注册绑定。
我不确定您是使用Ninject 1.x还是2.0 beta。两个版本的执行情况略有不同,但从概念上讲,它们是相同的。我将坚持使用版本1.x进行此讨论。我不知道的另一条信息是你的主程序是否实例化Ninject内核,你的库只是添加到该内核的绑定,或者你的库本身是否包含内核和绑定。我假设您需要将库中的绑定添加到主程序集中的现有Ninject内核。最后,我将假设您正在动态加载此库,并且它不是静态链接到主程序。
要做的第一件事是在库中定义一个ninject模块,在其中注册所有绑定 - 您可能已经这样做了,但值得一提。例如:
public class MyLibraryModule : StandardModule {
public override void Load() {
Bind<IMyService>()
.To<ServiceImpl>();
// ... more bindings ...
}
}
现在您的绑定包含在Ninject模块中,您可以在加载程序集时轻松注册它们。我们的想法是,一旦加载了程序集,就可以扫描所有从StandardModule派生的类型。一旦有了这些类型,就可以将它们加载到内核中。
// Somewhere, you define the kernel...
var kernel = new StandardKernel();
// ... then elsewhere, load your library and load the modules in it ...
var myLib = Assembly.Load("MyLibrary");
var stdModuleTypes = myLib
.GetExportedTypes()
.Where(t => typeof(StandardModule).IsAssignableFrom(t));
foreach (Type type in stdModuleTypes) {
kernel.Load((StandardModule)Activator.CreateInstance(type));
}
有一点需要注意,您可以进一步概括上述代码以加载多个库并注册多个类型。另外,正如我上面提到的,Ninject 2具有内置的这种功能 - 它实际上具有扫描目录,加载程序集和注册模块的能力。很酷。
如果您的情景与我概述的情况略有不同,则可能会采用类似的原则。
答案 3 :(得分:0)
你能控制客户端代码吗?如果是的话,我不会在加载程序集时尝试做魔术,而是去实现像Registry那样执行绑定的单个类,实现接口IRegistry。然后在加载过程中,您可以在程序集中查找IRegistry的实现并激发必要的方法。
您还可以在课程中拥有属性:
[Component(Implements=typeof(IMyDependency)]
查找这些属性并将其加载到客户端的容器中。
或者您可以查看MEF这是一种适用于这种情况的库。
答案 4 :(得分:-1)
据我所知,答案是否定的 。据我所知,你想在你的类库中配置你的IoC容器,如果是这样的话,这样做并不是一个好主意。如果你在类库中定义了绑定,那么依赖注入的用途是什么?我们使用依赖注入,以便我们可以在运行时注入依赖项,然后我们可以在不同的场景中注入不同的对象。虽然配置IoC容器的最佳位置是启动应用程序(因为IoC容器就像是应用程序的主干:))但它应该放在一个负责启动应用程序的引导程序。在简单的应用程序中它可以是Main方法。