2017-08-17 4 views
0

J'ai N validateurs sur mon aplication mais un client n'utilise pas tous les validateurs, j'ai par procédure toutes les classes que mon client actuel devra instancier.AutoFac WCF injection à réflexion

Ma couche d'affaires:

public class MyClass 
{ 
    public void MyMethod(int idClient) 
    { 
     //This array is returned by a procedure passing idClient 
     string[] validatorsName = { "ValidatorName", "ValidatorName2" }; 

     foreach (string name in validatorsName) 
     { 

      IValidator validator = (IValidator)Activator.CreateInstance(Type.GetType(name)); 
      //Error. I need pass the INameDB; 

      validator.Process(); 
     } 
    } 
} 

Mon Interface:

public interface IValidator 
{ 
    void Process(); 
} 

valideurs:

public class ValidatorName : IValidator 
{ 
    INameDB nameDB; 

    public ValidatorName(INameDB nameDB) 
    { 
     this.nameDB = nameDB; 
    } 

    public void Process() 
    { 
     nameDB.AnyThing(pedidoId); 
    } 
} 

public class ValidatorName2 : IValidator 
{ 
    INameDB2 nameDB; 

    public ValidatorName(INameDB2 nameDB) 
    { 
     this.nameDB = nameDB; 
    } 

    public void Process() 
    { 
     nameDB.AnyThing2(pedidoId); 
    } 
} 

public class ValidatorName3 : IValidator 
{ 
    INameDB2 nameDB; 

    public ValidatorName(INameDB2 nameDB) 
    { 
     this.nameDB = nameDB; 
    } 

    public void Process() 
    { 
     nameDB.AnyThing2(pedidoId); 
    } 
} 

Global, je pourrais enregistrer tous les validateurs et avec le IList<IValidator>, donc je supprimerait de la liste les validateurs dont je n'aurais pas besoin.

string[] validatorsName = { "ValidatorName", "ValidatorName2" }; 
validators = validators .Where(p => validatorsName .Contains(p.GetType().Name)).ToList(); 

mais j'ai beaucoup de classes, il serait enregistrer ce pas besoin.

My Global:

public class Global : System.Web.HttpApplication 
{ 

    protected void Application_Start(object sender, EventArgs e) 
    { 
     ContainerBuilder builder = new ContainerBuilder(); 
     builder.RegisterType<NameDB>().As<INameDB>(); 
     builder.RegisterType<NameDB2>().As<INameDB2>(); 

     //builder.RegisterType<ValidatorName1>().As<IValidator>(); 
     //builder.RegisterType<ValidatorName2>().As<IValidator>(); 
     //builder.RegisterType<ValidatorName3>().As<IValidator>(); 

     AutofacHostFactory.Container = builder.Build(); 
     //AutofacHostFactory.Container.Resolve<IList<IValidator>>(); 
    } 
} 

Ma question est de savoir comment puis-je détecter l'interface INameDB ou INameDB2, obtenir l'instance sur Autofac et l'utilisation sur Activator.CreateInstance?

Merci.

Répondre

0

Après quelques jours, je pouvais coder la solution:

Ma classe principale, je crée une méthode pour injection la liste des validateurs:

public class MyClass 
{ 
    private IList<IValidator> listValidators; 

    public void MyMethod(int idClient) 
    { 
     ExecuteValidations(idClient); 
    } 

    private void ValidatorInjection(int idClient) 
    { 
     listValidators = new List<IValidator>(); 
     //This array is returned by a procedure passing idClient 
     string[] validatorsName = { "ValidatorName", "ValidatorName2" }; 
     foreach (string name in validatorsName) 
     { 
      IValidator validador = (IValidator)Activator.CreateInstance(Type.GetType(name)); 
      listValidators.Add(validador); 
     } 
    } 

    private void ExecuteValidations(int idClient) 
    { 
     ValidatorInjection(idClient); 
     RunValidatorsList(); 
    } 

    private void RunValidatorsList() 
    { 
     foreach (var validator in listValidators) 
     { 
      validator.Process(); 
     } 
    } 
} 

Mes validateurs, il me fallait obtenir l'instance de base de données d'interface sur récipient avec INameDB2 db = AutofacHostFactory.Container.Resolve<INameDB2>();:

public class ValidatorName : IValidator 
{ 
    public void Process() 
    { 
     INameDB db = AutofacHostFactory.Container.Resolve<INameDB>(); 
     db.AnyThing(pedidoId); 
    } 
} 

public class ValidatorName2 : IValidator 
{ 
    public void Process() 
    { 
     INameDB2 db = AutofacHostFactory.Container.Resolve<INameDB2>(); 
     db.AnyThing2(pedidoId); 
    } 
} 

public class ValidatorName3 : IValidator 
{ 
    public void Process() 
    { 
     INameDB2 db = AutofacHostFactory.Container.Resolve<INameDB2>(); 
     db.AnyThing2(pedidoId); 
    } 
} 

global, je l'ai fait d'une manière que je ne ai pas besoin d'ajouter la ligne pour enregistrer une nouvelle classe qui IValidator mise en œuvre:

public class Global : System.Web.HttpApplication 
{ 
    protected void Application_Start(object sender, EventArgs e) 
    { 
     ContainerBuilder builder = new ContainerBuilder(); 
     builder.RegisterType<NameDB>().As<INameDB>(); 
     builder.RegisterType<NameDB2>().As<INameDB2>(); 

     string assembly = "MY_ASSEMBLY"; 
     builder.RegisterAssemblyTypes(Assembly.Load(assembly)).Where(t => t.IsAssignableTo<IValidator>()).AsImplementedInterfaces(); 

     AutofacHostFactory.Container = builder.Build(); 
    } 
}