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

加载程序集后执行的C#方法,c#,class,ninject,C#,Class,Ninject,我编写了一些C#类库,我想使用Ninject为我的类提供依赖注入。类库是否可以声明一些代码(方法),这些代码(方法)将在每次加载类库时执行。我需要它来定义Ninject的绑定。听起来您在寻找与C++的DllMain等价的东西。在C#中没有办法做到这一点 您能给我们提供一些关于您的场景的更多信息,以及为什么需要代码来执行DllMain风格的函数吗 在类型上定义静态构造函数并不能解决此问题。静态类型构造函数只能保证在以任何方式使用类型本身之前运行。您可以定义一个静态构造函数,在Dll中使用其他不访问

我编写了一些C#类库,我想使用Ninject为我的类提供依赖注入。类库是否可以声明一些代码(方法),这些代码(方法)将在每次加载类库时执行。我需要它来定义Ninject的绑定。

听起来您在寻找与C++的DllMain等价的东西。在C#中没有办法做到这一点

您能给我们提供一些关于您的场景的更多信息,以及为什么需要代码来执行DllMain风格的函数吗


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

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

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

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

[Component(Implements=typeof(IMyDependency)]
查找这些属性并将它们加载到客户端的容器中


或者,您可以查看哪一个库适用于此类情况。

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

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

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

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

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

public class MyLibraryModule : StandardModule {
  public override void Load() {
    Bind<IMyService>()
      .To<ServiceImpl>();
    // ... more bindings ...
  }
}
需要注意的是,您可以进一步概括上述代码,以加载多个库并注册多个类型。另外,正如我前面提到的,Ninject 2内置了这种功能——它实际上能够扫描目录、加载程序集和注册模块。很酷


如果您的场景与我概述的稍有不同,则可以采用类似的原则。

在很多情况下,您希望在类库中定义绑定。您可能在不同的库中有相同服务的不同实现,这两种实现可能在同一应用程序中同时相关,具体取决于服务使用的上下文。Ninject(和其他IoC一样)提供了定义上下文绑定的能力,因此能够基于某些提供的上下文激活不同的具体服务。
// 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));
}