2011-02-07 3 views
0

Dire que j'ai:résolution Nested

ProductA 
ProductB 

ProductScreen 

ProductAScreen1 : ProductScreen 
ProductAScreen2 : ProductScreen 

ProductBScreen1 : ProductScreen 
ProductBScreen2 : ProductScreen 

Comment puis-je le configurer de sorte que j'enregistrer les écrans localement au produit? Donc, quand je suis dans ProductA et que je passe IEnumerable, cela ne résout pas les écrans de ProductB? Je pensais que ce serait réalisable en utilisant quelque chose comme la portée à vie, mais il ne semble pas que je l'ai compris correctement.

Répondre

4

L'étendue de durée de vie est utilisée pour contrôler la durée de vie de l'instance. Vous parlez de contrôler la sélection. Pour cela, vous devriez regarder the metadata features dans Autofac.

Utilisation des métadonnées, vous pouvez « tag » chaque écran du produit, indiquant quel produit il appartient à:

builder.Register(c => new ProductAScreen1()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductA))); 
builder.Register(c => new ProductAScreen2()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductA))); 

builder.Register(c => new ProductBScreen1()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductB))); 
builder.Register(c => new ProductBScreen2()).As<ProductScreen>() 
    .WithMetadata<IProductScreenMetadata>(m => 
     m.For(am => am.ProductType, typeof(ProductB))); 

Ensuite, vous pouvez prendre une dépendance sur une IEnumerable<Lazy<ProductScreen, IProductScreenMetadata>> et résoudre les écrans selon le type de produit:

var productScreens = _screens.WHere(a => a.Metadata.ProductType == typeof(ProductA)); 

Mise à jour: pour être complet, voici une solution plus simple en utilisant the Keyed approach. Tout d'abord, l'inscription est beaucoup plus simple:

builder.RegisterType<ProductAScreen1>().Keyed<ProductScreen>(typeof(ProductA)); 
builder.RegisterType<ProductAScreen2>().Keyed<ProductScreen>(typeof(ProductA)); 
builder.RegisterType<ProductBScreen1>().Keyed<ProductScreen>(typeof(ProductB)); 
builder.RegisterType<ProductBScreen2>().Keyed<ProductScreen>(typeof(ProductB)); 

Pour résoudre un ensemble de services calées, nous allons devoir prendre une dépendance du type IIndex<,>:

public class SomeService  
{ 
    private IEnumerable<ProductScreen>> _screens; 
    public SomeService(IIndex<Type, IEnumerable<ProductScreen>> screens) 
    { 
     _screens = screens; 
    } 

    public void DoSomething() 
    { 
     var screensForProductA = _screens[typeof(ProductA)]; 
    } 
} 

Note: pour les curieux: au lieu de hardcoding les enregistrements de type, voici comment vous pouvez faire un enregistrement "par convention":

var assembly = ...; 
var productTypes = ...; // a collection of all the product types 

foreach(var productType in productTypes) 
{ 
    builder.RegisterAssemblyTypes(assembly) 
     .Where(t => typeof(ProductScreen).IsAssignableFrom(t)) 
     .Where(t => t.Name.StartsWith(productType.Name)) 
     .Keyed<ProductScreen>(productType); 
} 
+0

Merci Peter. Cela semble être une bonne option. J'ai essayé cela, avec l'enregistrement en utilisant .Keyed(). Ils semblent tous les deux des solutions décentes. – Mark

+0

Super, et oui, Keyed est plus facile dans ce scénario. Était trop concentré sur les trucs de métadonnées que j'ai oublié à ce sujet :) –