2009-05-24 19 views
5

Escribo alguna biblioteca de clase C# y deseo usar Ninject para proporcionar inyección de dependencia para mis clases. ¿Es posible que la biblioteca de la clase declare algún código (método) que se ejecutaría cada vez que se cargue la biblioteca de la clase? Necesito esto para definir enlaces para Ninject.Método C# que se ejecuta después de cargar el ensamblado

Respuesta

1

He usado Ninject bastante en los últimos 9 meses. Parece que lo que tienes que hacer es "cargar" tus módulos que existen en tu biblioteca en el kernel de Ninject para poder registrar los enlaces.

No estoy seguro de si está utilizando Ninject 1.x o la versión 2.0 beta. Las dos versiones realizan las cosas de forma ligeramente diferente, aunque conceptualmente, son las mismas. Me quedaré con la versión 1.x para esta discusión. La otra información que desconozco es si su programa principal está creando instancias del kernel Ninject y su biblioteca simplemente está agregando enlaces a ese núcleo, o si su biblioteca contiene el kernel y los enlaces. Supongo que debe agregar enlaces en su biblioteca a un kernel Ninject existente en el ensamblaje principal. Finalmente, supondré que carga dinámicamente esta biblioteca y que no está vinculada estáticamente al programa principal.

Lo primero que debe hacer es definir un módulo de ninject en su biblioteca en el que registre todos sus enlaces; puede que ya lo haya hecho, pero vale la pena mencionarlo.Por ejemplo:

public class MyLibraryModule : StandardModule { 
    public override void Load() { 
    Bind<IMyService>() 
     .To<ServiceImpl>(); 
    // ... more bindings ... 
    } 
} 

Ahora que las fijaciones están contenidas dentro de un módulo de Ninject, puede registrarse fácilmente cuando la carga de su montaje. La idea es que una vez que cargue su ensamblaje, puede escanearlo para todos los tipos derivados de StandardModule. Una vez que tenga estos tipos, puede cargarlos en el kernel.

// 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)); 
} 

Una cosa a tener en cuenta, puede generalizar el código anterior más para cargar múltiples bibliotecas y registrar múltiples tipos. Además, como mencioné anteriormente, Ninject 2 tiene este tipo de capacidad incorporada, en realidad tiene la capacidad de escanear directorios, cargar ensamblajes y registrar módulos. Muy genial.

Si su escenario es ligeramente diferente de lo que he descrito, es probable que se puedan adaptar principios similares.

6

Parece que está buscando el equivalente de DllMain de C++. No hay forma de hacer esto en C#.

¿Puede darnos más información acerca de su escenario y por qué necesita código para ejecutar en una función de estilo DllMain?

La definición de un constructor estático en un tipo no resuelve este problema. Solo se garantiza que un constructor de tipo estático se ejecutará antes de que el tipo se use de alguna manera. Puede definir un constructor estático, usar otro código dentro del DLL que no acceda al tipo y su constructor nunca se ejecutará.

-1

Por lo que yo sé la respuesta es no .Como entiendo que desea configurar su contenedor COI en la biblioteca de clases y si ese es el caso, no es una buena idea hacer that.If a definir sus fijaciones en su biblioteca de clases, entonces ¿para qué sirve la inyección de dependencia? utilizamos la inyección de dependencia para poder inyectar dependencias en tiempo de ejecución y luego podemos inyectar diferentes objetos en diferentes escenarios. Aunque el mejor lugar para configurar un contenedor IoC es la puesta en marcha de la aplicación (ya que un contenedor IoC es como una red troncal para una aplicación :)) pero debe colocarse en un bootstrap que sea responsable de iniciar la aplicación. En aplicaciones simples, puede ser el método principal.

+0

Hay muchas situaciones en las que le gustaría definir enlaces en una biblioteca de clases. Es posible que tenga diferentes implementaciones del mismo servicio en diferentes bibliotecas, las cuales pueden ser relevantes en la misma aplicación al mismo tiempo según el contexto en el que se utiliza el servicio. Ninject (al igual que otras IoC) ofrece la capacidad de definir enlaces contextuales, por lo que tiene la capacidad de activar diferentes servicios concretos basados ​​en algún contexto provisto. –

0

¿Puedes controlar el código del cliente? En caso afirmativo, en lugar de tratar de hacer magia al cargar el ensamblado, implementaría una única clase, como Registry, que hace los enlaces, implementando una interfaz IRegistry. Luego, durante la carga, puede buscar la implementación de IRegistry en su ensamblaje e iniciar los métodos necesarios.

También puede tener atributos en sus clases:

[Component(Implements=typeof(IMyDependency)] 

mirada para estos atributos y cargarlos al contenedor en el lado del cliente.

O puede echar un vistazo a MEF que es una biblioteca para este tipo de situaciones.

1

¿Has probado el evento AppDomain.AssemblyLoad? Dispara después de que se haya cargado un ensamblaje.

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