8

मैं सैंडरसन के प्रो ASP.NET MVC फ्रेमवर्क के ऊपर जा रहा हूँ और अध्याय 4 में वह Creating a Custom Controller Factory चर्चा करता है और ऐसा लगता है के साथ ASP.NET MVC में नियंत्रण (आईओसी) के उलट की स्थापना है कि मूल विधि, AddComponentLifeStyle या AddComponentWithLifeStyle, नियंत्रकों रजिस्टर करने के लिए इस्तेमाल किया अब पदावनत किया गया है:कैसल विंडसर

public class WindsorControllerFactory : DefaultControllerFactory 
{ 
    IWindsorContainer container; 

    public WindsorControllerFactory() 
    { 
     container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle"))); 

     // register all the controller types as transient 
     var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes() 
           where typeof(IController).IsAssignableFrom(t) 
           select t; 

     //[Obsolete("Use Register(Component.For<I>().ImplementedBy<T>().Named(key).Lifestyle.Is(lifestyle)) instead.")] 
     //IWindsorContainer AddComponentLifeStyle<I, T>(string key, LifestyleType lifestyle) where T : class; 
     foreach (Type t in controllerTypes) 
     { 
      container.Register(Component.For<IController>().ImplementedBy<???>().Named(t.FullName).LifeStyle.Is(LifestyleType.Transient)); 
     } 
    } 

    // Constructs the controller instance needed to service each request 
    protected override IController GetControllerInstance(Type controllerType) 
    { 
     return (IController)container.Resolve(controllerType); 
    } 
} 

नया सुझाव Register(Component.For<I>().ImplementedBy<T>().Named(key).Lifestyle.Is(lifestyle)) उपयोग करने के लिए है, लेकिन मैं समझ नहीं ImplementedBy<???>() विधि में लागू करने नियंत्रक प्रकार पेश करने के लिए कैसे। मैंने ImplementedBy<t>() और ImplementedBy<typeof(t)>() की कोशिश की, लेकिन मुझे कार्यान्वयन प्रकार में पास करने का उचित तरीका नहीं मिल रहा है। कोई विचार?

+0

कृपया विंडसर से संबंधित किसी भी चीज़ के लिए सैंडर्स की पुस्तक का उपयोग न करें, यह ** ** ** अभी तक पुराना है। –

+0

@ मॉरिसियो शफ़फर, मुझे एहसास है कि कुछ चीजें पुरानी हैं, लेकिन कुछ निफ्टी रत्न हैं जो उपयोगी हो सकते हैं ... विशेष रूप से, निर्भरता को हल करने में सहायता के लिए Web.config का उपयोग करना: उदा। एक रिपोजिटरी क्लास को प्रारंभ करने के लिए एक कनेक्शन स्ट्रिंग प्रदान करना आवश्यक है (हालांकि मुझे यह पता नहीं लगा है कि इसे अभी तक कैसे किया जाए)। – Kiril

+0

जो पुराना है, मैं ऐसा करने की अनुशंसा नहीं करता। –

उत्तर

6

मैं इस ControllerBuilder.SetControllerFactory और कोड आप ओपन सोर्स प्रोजेक्ट MvcContrib में पा सकते हैं का उपयोग कर कर रहा हूँ में एक खाली वर्ग है:

Global.asax.cs

protected void Application_Start() 
{ 
    ... 

    IWindsorContainer windsorContainer = new WindsorContainer(); 
    windsorContainer.RegisterControllers(Assembly.GetExecutingAssembly()); 
    ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(windsorContainer)); 

    ... 
} 

WindsorControllerFactory

public class WindsorControllerFactory : DefaultControllerFactory 
{ 
    private readonly IWindsorContainer _container; 

    public WindsorControllerFactory(IWindsorContainer container) 
    { 
     if (container == null) 
     { 
      throw new ArgumentNullException(); 
     } 

     _container = container; 
    } 

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
    { 
     if (controllerType == null) 
     { 
      throw new HttpException(); 
     } 

     if (!typeof(IController).IsAssignableFrom(controllerType)) 
     { 
      throw new ArgumentException(); 
     } 

     try 
     { 
      return (IController)_container.Resolve(controllerType); 
     } 
     catch (Exception ex) 
     { 
      throw new InvalidOperationException(); 
     } 
    } 

    public override void ReleaseController(IController controller) 
    { 
     IDisposable disposable = controller as IDisposable; 

     if (disposable != null) 
     { 
      disposable.Dispose(); 
     } 

     _container.Release(controller); 
    } 
} 

WindsorExtensions (MvcContrib देख)

public static class WindsorExtensions 
{ 
    public static IWindsorContainer RegisterController<T>(this IWindsorContainer container) where T : IController 
    { 
     container.RegisterControllers(typeof(T)); 

     return container; 
    } 

    public static IWindsorContainer RegisterControllers(this IWindsorContainer container, params Type[] controllerTypes) 
    { 
     foreach (Type type in controllerTypes) 
     { 
      if (ControllerExtensions.IsController(type)) 
      { 
       container.Register(Component.For(type).Named(type.FullName).LifeStyle.Is(LifestyleType.Transient)); 
      } 
     } 

     return container; 
    } 

    public static IWindsorContainer RegisterControllers(this IWindsorContainer container, params Assembly[] assemblies) 
    { 
     foreach (Assembly assembly in assemblies) 
     { 
      container.RegisterControllers(assembly.GetExportedTypes()); 
     } 

     return container; 
    } 
} 

ControllerExtensions (MvcContrib देख)

public static class ControllerExtensions 
{ 
    public static bool IsController(Type type) 
    { 
     return type != null 
       && type.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase) 
       && !type.IsAbstract 
       && typeof(IController).IsAssignableFrom(type); 
    } 
} 
+0

ताकि आप 'कार्यान्वित' निर्दिष्ट न करें ('रजिस्टर नियंत्रक' विधि में)? उसके साथ कोई समस्या नहीं है? – Kiril

+0

@Lirik: नहीं;) Castle.Windsor के लिए विस्तार विधि MvcContrib प्रोजेक्ट (http://mvccontrib.codeplex.com/) से ली गई है। मैंने फ़ाइल के लिंक के साथ अपना जवाब अपडेट कर दिया है। –

+0

@Lirik: मैं कैसल 2.5.2 और एएसपी.नेट एमवीसी 3 आरटीएम के साथ उपरोक्त कोड का उपयोग कर रहा हूं और अब तक कोई मुद्दा नहीं है। किसी भी तरह मैंने अभी देखा है कि MvcContrib.Castle प्रोजेक्ट को अब '[अप्रचलित]' के साथ चिह्नित किया गया है। आखिरकार विंडसर को लागू करने के बाद मुझे और अधिक अनुशंसित तरीके से जांच करनी होगी। –

-1

कुछ की तरह:

public void Register(IWindsorContainer container) 
    { 
     Assembly.GetAssembly(typeof(ControllersRegistrarMarker)).GetExportedTypes() 
       .Where(IsController) 
       .Each(type => container.AddComponentLifeStyle(
             type.Name.ToLower(), 
             type, 
             LifestyleType.Transient)); 
    } 

ControllersRegistrarMarker सिर्फ अपने नियंत्रकों विधानसभा

+2

'AddComonentLifeStyle' को बहिष्कृत किया गया है ... मैं इसका उपयोग कर सकता हूं, लेकिन मैं बदले गए फ़ंक्शन से जुड़े टिप्पणी द्वारा सुझाए गए अनुसार' कंटेनर। रजिस्ट्रार (...) 'फ़ंक्शन का उपयोग करना चाहूंगा। – Kiril

1

एक ट्यूटोरियल है (काम में लेकिन 9 भाग पहले से ही बाहर हैं) जो एएसपी.नेट एमवीसी here में विंडसर के उपयोग पर चर्चा करता है। यह सबसे अद्यतित है और विषय पर सामान्य उपयोग संसाधन को कवर करता है जहां तक ​​मुझे पता है।

+0

उस जानकारी के लिए धन्यवाद। – Kiril

1

@Lirik, एक अतिरिक्त के रूप में: यदि आप एमवीसी 3 का उपयोग करते हैं तो अपना खुद का कस्टम IControllerFactory हटा दें। विंडसर के साथ बस नियंत्रकों को पंजीकृत करें और IDependencyResolver को विंडसर कंटेनर के अंदर लागू करें।

अपने IDependencyResolver को एमवीसी निर्भरता रीसोलवर और DefaultControllerFactory के रूप में सेट करें स्वचालित रूप से कंटेनर में पंजीकृत नियंत्रकों को तार करेगा (DependencyResolver के माध्यम से)।

+0

क्षमा करें, मैं 'निर्भरता रीसोलवर' कैसे सेट करूं? (ध्यान दें कि मैं अभी भी पुस्तक और सीख रहा हूं, इसलिए अगर मैं स्पष्ट होना चाहिए तो मैं क्षमा चाहता हूं) मैंने इस परियोजना को खरोंच से बनाया है ... मैं कहां से "मेरा अपना" आईकंट्रोलर फैक्टरी 'देखने की उम्मीद करूंगा? मैंने 'Application_Start' विधि में 'विंडसर कंट्रोलर फैक्ट्री' सेट किया है, लेकिन 'विंडसर कंट्रोलर फैक्टरी' सेट करने से पहले वहां कोई अन्य 'आईकंट्रोलर फैक्टरी' सेट नहीं किया गया था। – Kiril

+1

मैंने 'निर्भरता रिसेल्वर' पर कुछ जानकारी प्राप्त करने का प्रयास किया और मैं [कुछ लोग सुझाव देते हैं कि हमें विंडसर के लिए एक को लागू नहीं करना चाहिए] (http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface -is.html? utm_source = feedburner और utm_medium = फ़ीड और utm_campaign = फ़ीड% 3 ए + CodeRant +% 28Code + शेख़ी% 29)। – Kiril

+0

@ लीरिक, आपको अपने आप पर निर्भरता रिसेल्वर को भी लागू करने की आवश्यकता नहीं है। [CommonServiceLocator] (http://commonservicelocator.codeplex.com) को 'निर्भरता रीसोलवर' के रूप में सेट किया जा सकता है। बस [सीएसएल के लिए विंडसर एडाप्टर] लें (http://commonservicelocator.codeplex.com/wikipage?title=Castle%20Windsor%20Adapter&referringTitle=Home) और इसे इस तरह सेट करें: 'निर्भरताResolver.SetResolver (नया WindsorServiceLocator (windsorContainerInstance)); 'डिफ़ॉल्ट रूप से' डिफॉल्ट कंट्रोलर फैक्टरी 'सेट-ऑफ-द-बॉक्स सेट होने के बाद से आपको नियंत्रक फ़ैक्टरी सेट अप करने की आवश्यकता नहीं है। –

संबंधित मुद्दे