Domanda

Prendi il seguente programma inutile:

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer unityContainer = new UnityContainer();
        IWindsorContainer windsorContainer = new WindsorContainer();

        Program unityProgram = unityContainer.Resolve<Program>();
        Program castleProgram = windsorContainer.Resolve<Program>();
    }
}

UnityContainer mi restituirà un'istanza di Program, in cui il contenitore Windsor genererà ComponentNotFoundException.

Riesco a vedere argomenti per entrambi i comportamenti e non mi dispiace con cui finisco, tuttavia Prism V2 Drop 8 (l'ultimo al momento della stesura) fa affidamento sul comportamento di Unity internamente, richiedendo classi che non sono state registrate.

Invece di trovare e registrare tutte queste classi per Prism, preferirei che Windsor si comporti come Unity. Non ho trovato nulla su Google per aiutarmi a farlo (anche se la mia terminologia potrebbe essere errata) e la documentazione di Windsor è piuttosto negativa ...

Qualcuno può suggerire una soluzione a questo problema?

È stato utile?

Soluzione

Windsor al momento non lo supporta, ed è in base alla progettazione. Il ragionamento è che dovresti registrare esplicitamente i tipi di cui hai bisogno in modo da non ottenere oggetti configurati male.

Esiste tuttavia la possibilità che venga aggiunto un hook per creare tipi non registrati ad un certo punto nel prossimo futuro, poiché ciò è necessario per la funzione di integrazione WCF. (Modifica - è stato aggiunto in v2.1 - dai un'occhiata a ILazyComponentLoader s)

In ogni caso , indipendentemente dai caricatori di componenti pigri, il meglio che puoi fare è utilizzare l'API fluente per registrare in batch tutti i tipi da un assembly che corrisponda in anticipo ai criteri necessari. Non è molto più codice e dormirai meglio di notte.

Usa i caricatori pigri solo se non hai davvero abbastanza informazioni all'avvio (nella tua root di composizione ) per determinare quali componenti ti occorreranno.

Altri suggerimenti

Windsor non lo supporta immediatamente, ma è possibile creare metodi di estensione per fare ciò:

static class WindsorExtensions
{
    public static object ResolveType(this IWindsorContainer container, Type type)
    {
        if ( type.IsClass && !container.Kernel.HasComponent(type) )
            container.Kernel.AddComponent(type.FullName, type, LifestyleType.Transient);
        return container.Resolve(type);
     }

     public static T ResolveType<T>(this IWindsorContainer container)
     { return (T)ResolveType(container, typeof(T)); }
}

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer unityContainer = new UnityContainer();
        IWindsorContainer windsorContainer = new WindsorContainer();

        Program unityProgram = unityContainer.Resolve<Program>();
        Program castleProgram = windsorContainer.ResolveType<Program>();
    }
}

Krzysztof non ha paura di collegarti al tuo blog qui :) http://devlicious.com/blogs/krzysztof_kozmic/archive/2009/11/16/castle-windsor-lazy-loading.aspx

Inoltre, ho trovato utile questa semplice implementazione nella mia app WPF, rimuovendo il limite di stringhe e sei vicino al caso generale

public class ViewModelLoader : Castle.MicroKernel.Resolvers.ILazyComponentLoader {
    public IRegistration Load(string key, Type service)
    {
        if (service == null)
            return null;
        if (service.Name.EndsWith("ViewModel", StringComparison.CurrentCultureIgnoreCase))
            return Component.For(service).Named(key);
        else
            return null;
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top