2012-07-23 102 views
0

我试图创建一个工厂,它将在字典中包含“子”控制器列表。这些子控制器必须包含工厂,以便他们可以访问其他子控制器。这里是工厂:如何创建一个包含工厂控制器的工厂

public interface IChildControllerFactory 
{ 
    IChildController GetChildController(object item); 
} 


public class ChildControllerFactory : IChildControllerFactory 
{ 
    private Dictionary<string, IChildController> _childControllerDictionary; 

    public ChildControllerFactory(IEnumerable<IChildController> childControllers) 
    { 
     var childControllerDictionary = new Dictionary<string, IChildController>(); 

     //code to build dictionary 
     _childControllerDictionary = childControllerDictionary; 
    } 

    public IChildController GetChildController(object item) 
    { 
     return _childControllerDictionary.Where(x => x.Key == item.GetType().Name).Select(x => x.Value).First(); 
    } 
} 

下面是一个子控制器的例子:

public class ChildController : Controller, IChildController<TViewModel, TModel> 
{ 
    private IChildControllerFactory _childControllerFactory; 

    public ChildController(IChildControllerFactory childControllerFactory) //this will cause a circular reference 
    { 
     _childControllerFactory = childControllerFactory; 
    } 

    public ActionResult GetChildViewModel(object child) 
    { 
     var model = _childControllerFactory.GetChildController(child).ToViewModel(survey); 
     return PartialView("Child.ascx", model); 
    } 
} 

而且继承接口:

public interface IChildController<TViewModel, TModel> 
{ 
    int Create(object item); 
    object Save(object item); 
    object ToViewModel(object item); 
} 

子控制器都注册,工厂被指定为具有Structure Map的Singleton。

由于子控制器需要Factory,所以在使用依赖注入的构造函数中设置工厂将导致循环引用,因为初次初始化Factory时,它将初始化所有子控制器,并且每个子控制器将尝试初始化工厂(已经执行)。

我如何让工厂实例化所有的子控制器,然后让它可以从那些子控制器访问?

回答

1

让我们来思考一下。 A childController只有在分配工厂权限后才能使用?所以在创建childFactory之前,childControll事实上是无用的。这说我会做这样的事情:

public class ChildController : Controller, IChildController<TViewModel, TModel> 
{ 
    private IChildControllerFactory _childControllerFactory; 

    public ChildController() 
    { 
    } 

    public void setChildControllerFactory(IChildControllerFactory childControllerFactory) 
    { 
     _childControllerFactory = childControllerFactory; 
    } 

    public ActionResult GetChildViewModel(object child) 
    { 
     var model = _childControllerFactory.GetChildController(child).ToViewModel(survey); 
     return PartialView("Child.ascx", model); 
    } 
} 

所以你ChildControllerFactory会是这样:

public ChildControllerFactory(IEnumerable<IChildController> childControllers) 
{ 
    var childControllerDictionary = new Dictionary<string, IChildController>(); 
    _childControllerDictionary = childControllerDictionary; 
    for(IChildController i in _childControllerDictionary) i.setChildControllerFactory(this); 
} 

我没有测试,但我没有看到具体对象的必要性有工厂在构造函数中传入,因为您在工厂中存储了此对象的字典。

+0

这看起来似乎解决了我所遇到的大多数问题,但当页面有请求时,_childControllerFactory如何设置?我们知道我们不能在构造函数中使用依赖注入,但我想我可以重写Initialize控制器方法来获取和设置工厂实例。这会推荐吗? – 2012-07-24 01:03:50

+0

你是指这个吗? http://bubblogging.wordpress.com/2012/06/04/mvc-controller-factory/ – dierre 2012-07-24 01:34:49