加载程序集后执行的C#方法

我写了一些C#类库,我想使用Ninject为我的类提供dependency injection。 类库是否有可能声明一些代码(方法),这些代码(方法)将在加载类库时每次执行。 我需要这个来定义Ninject的绑定。

在过去的9个月里,我使用了Ninject。 听起来你需要做的是将你的库中存在的模块“加载”到Ninject内核中以注册绑定。

我不确定你是使用Ninject 1.x还是2.0 beta。 这两个版本的执行情况略有不同,但从概念上讲,它们是相同的。 我将坚持使用版本1.x进行此讨论。 我不知道的另一条信息是你的主程序是否实例化Ninject内核,你的库只是添加绑定到该内核,或者你的库本身包含内核和绑定。 我假设您需要在库中将绑定添加到主程序集中的现有Ninject内核。 最后,我将假设您正在动态加载此库,并且它不是静态链接到主程序。

首先要做的是在库中定义一个ninject模块,在其中注册所有绑定 – 您可能已经这样做了,但值得一提。 例如:

public class MyLibraryModule : StandardModule { public override void Load() { Bind() .To(); // ... 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具有内置的这种function – 它实际上具有扫描目录,加载程序集和注册模块的能力。 很酷。

如果您的情景与我概述的情况略有不同,则可能会采用类似的原则。

听起来你正在寻找相当于C ++的DllMain。 在C#中无法做到这一点。

您能否向我们提供有关您的场景的更多信息以及为什么需要在DllMain样式函数中执行代码?

在类型上定义静态构造函数不能解决此问题。 静态类型构造函数仅保证在以任何方式使用类型本身之前运行。 您可以定义一个静态构造函数,使用Dll中不访问该类型的其他代码,它的构造函数永远不会运行。

您是否尝试过AppDomain.AssemblyLoad事件? 它在加载程序集后触发。

 AppDomain.CurrentDomain.AssemblyLoad += (s, e) => { Assembly justLoaded = e.LoadedAssembly; // ... etc. }; 

你能控制客户端代码吗? 如果是的话,我不会在加载程序集时尝试做魔法,而是去实现像Registry这样的单个类来执行绑定,实现接口IRegistry。 然后在加载过程中,您可以在程序集中查找IRegistry的实现并触发必要的方法。

您还可以在类上拥有属性:

 [Component(Implements=typeof(IMyDependency)] 

查找这些属性并将其加载到客户端的容器中。

或者你可以看看MEF ,这是一个适合这种情况的库。

据我所知,答案是否定的。据我所知,你想在你的类库中配置你的IoC容器,如果是这样的话那就不好了。如果你在类库中定义绑定那么什么是使用dependency injection? 我们使用dependency injection,以便我们可以在运行时注入依赖项,然后我们可以在不同的场景中注入不同的对象。虽然配置IoC容器的最佳位置是启动应用程序(因为IoC容器就像应用程序的主干:))但它应该放在一个负责启动应用程序的引导程序。在简单的应用程序中,它可以是Main方法。