2010-10-04 7 views
5

Warum .net MVC-Quellcode ControllerBuilder einen Delegaten verwenden, um die Controller Factory ?:MVC-Quellcode Singletonmuster

private Func<IControllerFactory> _factoryThunk; 

public void SetControllerFactory(IControllerFactory controllerFactory) { 
    _factoryThunk =() => controllerFactory; 
} 

Warum kann sie nicht nur die Controller direkt zuweisen zuweisen ?, das heißt:

private IControllerFactory _factory; 

public void SetControllerFactory(IControllerFactory controllerFactory) { 
    _factory = controllerFactory; 
} 

public void SetControllerFactory(Type controllerFactoryType) { 
    _factory = (IControllerFactory)Activator.CreateInstance(controllerFactoryType); 
} 

Antwort

4

Der Grund, dass _factoryThunk derzeit als Func<IControllerFactory> definiert ist, dass es ein generisches Mittel ist sowohl Überlastungen zu unterstützen:

void SetControllerFactory(Type); 
void SetControllerFactory(IControllerFactory); 

Die Umsetzung des ersten nutzt die Tatsache, dass _factoryThunk ist ein Func durch das Func inline deklarieren von Activator mit dem Type lazily zu instanziiert:

this._factoryThunk = delegate { 
    IControllerFactory factory; 
    try 
    { 
     factory = (IControllerFactory) Activator.CreateInstance(controllerFactoryType); 
    } 
    catch (Exception exception) 
    { 
     throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, MvcResources.ControllerBuilder_ErrorCreatingControllerFactory, new object[] { controllerFactoryType }), exception); 
    } 
    return factory; 
}; 

Daher ist der Grund, warum die andere Überlastung sieht aus wie es ist unechte Implementierung ist, dass seit _factoryThunk als Func erklärt wird, würde die Zeile, die Sie vorschlagen, nicht einmal zusammengestellt:

_factoryThunk = controllerFactory; 

_factoryThunk ist ein Func<IControllerFactory>, während controllerFactory ist ein IControllerFactory - inkompatible Typen.

+0

Die Frage ist, warum brauchen sie die faule Instanziierung? Die zweite Methode könnte _factory = (IControllerFactory) Activator.CreateInstance (controllerFactoryType) sein; Ich habe die Frage aktualisiert, um klarer zu sein – JontyMC

+0

@JontyMC, du hast absolut Recht, ich habe diese Nuance vorher verpasst. Nachdem ich den Quellcode ein wenig genauer untersucht habe, glaube ich, dass die Erklärung für das Design darin besteht, dass es den Implementern von IControllerFactory ermöglicht wird, den Zustand für einen spezifischen Controller, den sie instanziiert, beizubehalten. Das Design führt zu einer 1-1-Zuordnung zwischen Instanzen eines Controllers und Instanzen ihrer IControllerFactory. Auf diese Weise könnte die Implementierung von IControllerFactory beispielsweise an der Instanz des Controllers hängen, die in einem Feld zur späteren Verwendung instanziiert wird. (Ich bin mir nicht sicher, warum du das willst) –