2010-10-04 30 views
5

¿Por qué .net MVC código fuente ControllerBuilder utilizar un delegado para asignar el controlador de la fábrica ?:MVC patrón de código fuente Singleton

private Func<IControllerFactory> _factoryThunk; 

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

Por qué no puede simplemente asignar el ControllerFactory directamente ?, es decir:

private IControllerFactory _factory; 

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

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

Respuesta

4

La razón de que _factoryThunk se define actualmente como un Func<IControllerFactory> es que es un medio genérico para apoyar tanto a sobrecargas:

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

La aplicación de la primera se utiliza el hecho de que _factoryThunk es una Func declarando que Func en línea mediante el uso de Activator crear una instancia del Type perezosamente:

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; 
}; 

Por lo tanto, la razón por la otra sobrecarga parece que tiene una aplicación falsa es que desde _factoryThunk se declara como un Func, la línea que usted propone no habría incluso compilado:

_factoryThunk = controllerFactory; 

_factoryThunk es un Func<IControllerFactory> mientras que controllerFactory es un IControllerFactory - tipos incompatibles.

+0

La pregunta es ¿por qué necesitan la creación de instancias perezosas? El segundo método podría ser _factory = (IControllerFactory) Activator.CreateInstance (controllerFactoryType); He actualizado la pregunta para ser más claro – JontyMC

+0

@JontyMC, tienes toda la razón, me perdí ese matiz antes. Después de examinar un poco más el código fuente, creo que la explicación para el diseño es permitirles a los implementadores de IControllerFactory mantener el estado para un Controlador específico que ejemplifique. es decir, el diseño da como resultado un mapeo 1-1 entre las instancias de un Controlador y las instancias de su IControllerFactory. De esta manera, la implementación de IControllerFactory podría, por ejemplo, aferrarse a la instancia del Controlador que crea una instancia en un campo para su uso posterior. (no estoy seguro por qué querrías) –