2012-08-27 10 views
5

Estoy creando un sitio web usando Orchard CMS y tengo un proyecto externo de .NET escrito con Ninject para inyección de dependencias que me gustaría usar junto con un módulo dentro de Orchard CMS. Sé que Orchard usa Autofac para inyección de dependencia y esto me está causando problemas ya que nunca antes había trabajado con DI.¿Puedo usar mi proyecto Ninject .NET dentro de Orchard CMS?

He creado un módulo Autofac, UserModule, que registra la fuente, UserRegistrationSource, así:

UserModule.cs

public class UserModule : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterSource(new UserRegistrationSource()); 
    } 
} 

UserRegistrationSource.cs

public class UserRegistrationSource : IRegistrationSource 
{ 
    public bool IsAdapterForIndividualComponents 
    { 
     get { return false; } 
    } 

    public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor) 
    { 
     var serviceWithType = service as IServiceWithType; 
     if (serviceWithType == null) 
      yield break; 

     var serviceType = serviceWithType.ServiceType; 
     if (!serviceType.IsInterface || !typeof(IUserServices).IsAssignableFrom(serviceType) || serviceType != typeof(IUserServices)) 
      yield break; 

     var registrationBuilder = // something... 

     yield return registrationBuilder.CreateRegistration(); 
    } 
} 

UserServices.cs

public interface IUserServices : IDependency 
{ 
    void Add(string email, string password); 
} 

public class UserServices : IUserServices 
{ 
    private readonly EFMembershipManager _manager; 

    public UserServices(EFMembershipManager manager) 
    { 
     _manager = manager; 
    } 

    public void Add(string email, string password) 
    { 
     _manager.createUser(email, password); 
    } 
} 

EFMembershipManager.cs constructor

public EFMembershipManager(ServerRepository db, 
          ServerRepositoryMembershipProvider membershipProvider, 
          string testUsername, 
          string serverUsername) 
{ 
... 
} 

EFMembershipManager es una clase del proyecto externo que utiliza Ninject para DI de y utiliza ServerRepository y ServerRepositoryMembershipProvider los cuales también se inyectan usando Ninject.

Y ahora estoy atascado ...

En caso UserRegistrationSource lleve el envase Ninject (núcleo) como un argumento del constructor y tratar de encontrar el servicio IUserServices y mediar en los resuelve al kernel Ninject y devolver una vacía ¿Enumerable para que Autofac no intente resolver nada relacionado con IUserServices o este es el enfoque equivocado?

+1

¿Puede explicar por qué necesitaría una reescritura? Me parece que lo único que debe modificarse es el código que se trata con la inyección. Mencionas problemas. ¿Qué son específicamente? –

+1

@BertrandLeRoy La reescritura proviene del hecho de que el proyecto externo tiene muchas inyecciones de dependencia y referencias a otros proyectos que también usan Ninject para la inyección de dependencias. Entonces habrá muchas modificaciones para que todo funcione. El problema que estoy enfrentando es simplemente cómo puedo hacer referencia al proyecto externo en mi módulo Orchard sin tener que convertir todas las inyecciones de Ninject a las inyecciones de Autofac. Si eso es posible. – Mattias

+0

No creo que haya otra manera o si podrá hacer que esto funcione. Sería mejor mantener ese proyecto externo externo. –

Respuesta

4

Autofac admite registration sources (y más en las fuentes de registro here). Una fuente de registro es un servicio que el contenedor consultará cuando intente resolver un tipo. La fuente puede responder, ya sea con un medio para construir el tipo, o una lista vacía que indica que la fuente no puede proporcionar el tipo solicitado.

En su caso, podría implementarse una fuente de registro que intente resolver el tipo solicitado desde su contenedor Ninject.

No estoy muy familiarizado con Orchard, pero supongo que usa archivos de configuración para configurar Autofac. Mi sugerencia es que cree a simple Autofac module que registre la implementación de su fuente de registro, y que configure Orchard en load the module from config.

+0

Bien, buena respuesta. Algunos seguimientos ... ¿Debería la fuente de registro identificar el servicio que está conectado al proyecto externo, 'IUserServices', e instruir al contenedor Ninject (kernel) para resolverlo y devolver un enumerable vacío que le indique a Autofac que no resuelva los tipos solicitados o este es el enfoque equivocado? – Mattias

+0

Mi idea es que, dado que será Autofac quien realice la solicitud inicial de servicios, se preguntará a la fuente si es compatible con 'IUserServices' (y cualquier otro servicio para el caso). Entonces debería intentar resolver ese servicio desde Ninject. Si Ninject contiene el servicio, puede devolver la instancia desde la fuente. Si no, la fuente vuelve vacía. –

Cuestiones relacionadas