2010-10-04 54 views
5

为什么.NET MVC源代码ControllerBuilder类使用委托给控制器工厂?:MVC源代码Singleton模式

private Func<IControllerFactory> _factoryThunk; 

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

为什么不能只是直接分配的ControllerFactory ?,即分配:

private IControllerFactory _factory; 

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

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

回答

4

_factoryThunk当前被定义为一个Func<IControllerFactory>的原因是,它是一个通用的手段来支持重载:

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

第一个实现使用的事实,_factoryThunkFunc通过使用Activator宣布Func内嵌实例化Type懒洋洋地:

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

因此,有理由对其他重载看起来有一个杂散实现是因为_factoryThunk被声明为Func,你提出行根本不会编译:

_factoryThunk = controllerFactory; 

_factoryThunkFunc<IControllerFactory>controllerFactoryIControllerFactory - 不兼容的类型。

+0

问题是为什么他们需要懒惰的实例?第二种方法可以是_factory =(IControllerFactory)Activator.CreateInstance(controllerFactoryType);我已经更新了这个问题,以便更清楚 – JontyMC 2010-10-05 10:30:41

+0

@JontyMC,你说得对,我错过了那个细微差别。在详细了解源代码之后,我相信设计的解释是允许IControllerFactory的实现者为其实例化的特定控制器维护状态。即设计导致Controller的实例与其IControllerFactory的实例之间的1-1映射。这样,IControllerFactory的实现可以挂在它实例化的字段中的Controller实例上供以后使用。 (不知道为什么你会想要虽然) – 2010-10-05 14:51:36