मैं asp.net वेब फॉर्म पर Ninject या DI कैसे लागू कर सकता हूं?


83

एमवीसी एप्लिकेशन पर काम करने के लिए इसके कई उदाहरण हैं। यह वेब प्रपत्रों पर कैसे किया जाता है?

जवाबों:


79

यहाँ WebForms के साथ Ninject का उपयोग करने के चरण दिए गए हैं।

चरण 1 - डाउनलोड

दो डाउनलोड आवश्यक हैं - Ninject-2.0.0.0-release-net-3.5 और WebForm एक्सटेंशन Ninject.Web_1.0.0.0_With.log4net (एक NLog विकल्प है)।

निम्न फ़ाइलों को वेब एप्लिकेशन में संदर्भित किया जाना चाहिए: Ninject.dll, Ninject.Web.dll, Ninject.Extensions.Logging.dll और Ninject.Extensions.Logging.Log4net.dll।

चरण 2 - Global.asax

ग्लोबल क्लास को कंटेनर बनाने Ninject.Web.NinjectHttpApplicationऔर कार्यान्वित करने की आवश्यकता है CreateKernel(), जो कंटेनर बनाता है:

using Ninject; using Ninject.Web;

namespace Company.Web {
    public class Global : NinjectHttpApplication


        protected override IKernel CreateKernel()
        {
            IKernel kernel = new StandardKernel(new YourWebModule());
            return kernel;
        }

StandardKernelनिर्माता एक लेता है Module

चरण 3 - मॉड्यूल

मॉड्यूल, इस मामले में YourWebModule, वेब अनुप्रयोग के लिए आवश्यक सभी बाइंडिंग को परिभाषित करता है:

using Ninject;
using Ninject.Web;

namespace Company.Web
{
    public class YourWebModule : Ninject.Modules.NinjectModule
    {

        public override void Load()
        {
            Bind<ICustomerRepository>().To<CustomerRepository>();
        }   

इस उदाहरण में, जहाँ भी ICustomerRepositoryइंटरफ़ेस संदर्भित है कंक्रीट CustomerRepositoryका उपयोग किया जाएगा।

चरण 4 - पृष्ठ

एक बार ऐसा करने पर प्रत्येक पृष्ठ को इनहेरिट करने की आवश्यकता होती है Ninject.Web.PageBase:

  using Ninject;
    using Ninject.Web;
    namespace Company.Web
    {
        public partial class Default : PageBase
        {
            [Inject]
            public ICustomerRepository CustomerRepo { get; set; }

            protected void Page_Load(object sender, EventArgs e)
            {
                Customer customer = CustomerRepo.GetCustomerFor(int customerID);
            }

The InjectAttribute -[Inject]- NinRject को ICustomerRepositoryCustomerRepo प्रॉपर्टी में इंजेक्ट करने के लिए कहता है ।

यदि आपके पास पहले से ही एक आधार पृष्ठ है तो आपको सिर्फ अपना आधार पृष्ठ Ninject.Web.PageBase से प्राप्त करना होगा।

चरण 5 - मास्टर पृष्ठ

अनिवार्य रूप से, आपके पास मास्टर पृष्ठ होंगे, और एक मास्टरपेज को इंजेक्ट की गई वस्तुओं तक पहुंचने की अनुमति देने के लिए आपको अपने मास्टर पृष्ठ को Ninject.Web.MasterPageBaseनिम्न से प्राप्त करना होगा :

using Ninject;
using Ninject.Web;

namespace Company.Web
{
    public partial class Site : MasterPageBase
    {

        #region Properties

        [Inject]
        public IInventoryRepository InventoryRepo { get; set; }     

चरण 6 - स्थैतिक वेब सेवा के तरीके

अगली समस्या स्थैतिक तरीकों में इंजेक्ट करने में सक्षम नहीं थी। हमारे पास कुछ Ajax PageMethods थे, जो स्पष्ट रूप से स्थिर हैं, इसलिए मुझे विधियों को एक मानक वेब सेवा में स्थानांतरित करना पड़ा। फिर से, वेब सेवा को निनॉज़ क्लास से प्राप्त करना होगा - Ninject.Web.WebServiceBase:

using Ninject;
using Ninject.Web;    
namespace Company.Web.Services
{

    [WebService(Namespace = "//tempuri.org/">http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]    
    [System.Web.Script.Services.ScriptService]
    public class YourWebService : WebServiceBase
    {

        #region Properties

        [Inject]
        public ICountbackRepository CountbackRepo { get; set; }

        #endregion

        [WebMethod]
        public Productivity GetProductivity(int userID)
        {
            CountbackService _countbackService =
                new CountbackService(CountbackRepo, ListRepo, LoggerRepo);

अपने जावास्क्रिप्ट में आपको मानक सेवा का संदर्भ लेना होगा - Company.Web.Services.YourWebService.GetProductivity(user, onSuccess)बजाय इसके PageMethods.GetProductivity(user, onSuccess)

एकमात्र अन्य समस्या जो मुझे मिली, वह थी उपयोगकर्ता नियंत्रण में वस्तुओं को इंजेक्ट करना। हालांकि यह संभव है कि आप अपने खुद के आधार यूजरक्रोन्ट्रोल को Ninject क्षमताओं के साथ बनाएं, मैंने यह पाया कि आवश्यक वस्तु के लिए उपयोगकर्ता नियंत्रण में प्रॉपर्टी को जोड़ना और कंटेनर पेज में प्रॉपर्टी सेट करना संभव है। मुझे लगता है कि बॉक्स से बाहर UserControls का समर्थन Ninject "टू-डू" सूची में है।

Ninject जोड़ना काफी सरल है और यह एक jectququent IoC समाधान है। बहुत से लोग इसे पसंद करते हैं क्योंकि कोई Xml कॉन्फ़िगरेशन नहीं है। इसमें अन्य उपयोगी "ट्रिक्स" हैं जैसे कि ऑब्जेक्ट्स को सिर्फ उन्नीस सिंटैक्स के साथ सिंग्लेटन्स में बदलना - Bind<ILogger>().To<WebLogger>().InSingletonScope()। WebLogger को वास्तविक सिंगलटन इम्प्लांटेशन में बदलने की कोई आवश्यकता नहीं है, मुझे यह पसंद है।


1
यह एक उपचार का काम करता है, लेकिन मैंने एक नए WebForms ऐप (टेम्प्लेट से) पर यह प्रयास किया और पाया कि जब Global.asax.cs फ़ाइल में डिफ़ॉल्ट सत्र विधियाँ थीं (जैसे Application_Start) तो ऐप ने एक गुप्त त्रुटि लौटा दी। यह स्पष्ट हो सकता है कि आपको इन्हें हटाने की आवश्यकता है (जैसा कि इन्हें NinjectHttpApplication में लागू किया गया है), लेकिन इसने मुझे बाहर कर दिया।
मैट

खुशी है कि यह मददगार था। त्रुटि अजीब लगती है, अपवाद क्या था? मैं Application_Start में कोड है और यह ठीक काम करता है।
जो रैथर

3
मैं सिर्फ supertype विधि NinjectHttpApplication.Application_Start को Global.asax.cs फ़ाइल के Application_Start पद्धति से कॉल करना भूल गया। काम करता है जब मैं ऐसा करता हूं, अन्यथा यह टूट गया।
मैट

1
बिल्कुल, अब मैं जिस एप्लिकेशन पर काम कर रहा हूं, उसका आधार पृष्ठ (हमेशा एक अच्छा विचार) है, बस पेज पेज को लागू करने के लिए आधार पृष्ठ प्राप्त करें।
जो रैटजर

2
यह अब पुराना लगता है। NuGet पैकेज, Ninject.web में ऐप को बूटस्ट्रैप करने के लिए कुछ कोड शामिल हैं, जिससे NinjectHttpApplication अप्रचलित से सीधे विरासत की आवश्यकता होती है?
रयानडॉ

68

यह Ninject v3.0 (4/12/2012 के रूप में) की रिहाई के साथ आसान हो गया है। इंजेक्शन को HttpModule के माध्यम से कार्यान्वित किया जाता है, ताकि आपके पृष्ठों को किसी कस्टम पेज / मास्टरपेज से इनहेरिट करने की आवश्यकता न हो। यहां त्वरित स्पाइक के लिए चरण (और कोड) दिए गए हैं।

  1. एक नया ASP.NET WebForms प्रोजेक्ट बनाएं
  2. Ninject.Web lib जोड़ने के लिए NuGet का उपयोग करें (जो Ninject.Web.Common और Ninject libs को भी नीचे लाएगा)
  3. App_Start / NinjectWebCommon.cs / RegisterServices विधि में अपने कस्टम बाइंडिंग को पंजीकृत करें
  4. अपने पृष्ठों पर विशेषता इंजेक्शन का उपयोग करें

NinjectWebCommon / RegisterServices

    /// <summary>
    /// Load your modules or register your services here!
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IAmAModel>().To<Model1>();
    } 

चूक

public partial class _Default : System.Web.UI.Page
{

    [Inject]
    public IAmAModel Model { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        System.Diagnostics.Trace.WriteLine(Model.ExecuteOperation());
    }
}

Site.Master

public partial class SiteMaster : System.Web.UI.MasterPage
{

    [Inject]
    public IAmAModel Model { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        System.Diagnostics.Trace.WriteLine("From master: " 
            + Model.ExecuteOperation());
    }
}

मॉडल

public interface IAmAModel
{
    string ExecuteOperation();         
}

public class Model1 : IAmAModel
{
    public string ExecuteOperation()
    {
        return "I am a model 1";
    }
}

public class Model2 : IAmAModel
{
    public string ExecuteOperation()
    {
        return "I am a model 2";
    }
}

आउटपुट विंडो से परिणाम

I am a model 1
From master: I am a model 1

हाय जेसन ... मुझे लगता है कि लागू करने की कोशिश कर रहा हूँ ... NuGet ठीक से Ninject.Web परिवाद मिला ... यह App_Start पर बूटस्ट्रैपर बनाया ... मैंने डिबग करने के लिए RegisterServices पर एक ब्रेकप्वाइंट जोड़ने की कोशिश की, लेकिन यह कभी नहीं मिलता है ... क्या मुझे कुछ और जोड़ना है?
पॉल

1
@Paul आप डिबगिंग शुरू करने के लिए Debugger.Break () RegisterServices विधि में डाल सकते हैं।
बोगिन सेप

5
हाय जेसन। मुझे यह काम करने में परेशानी हो रही है, इसलिए मैं सोच रहा था कि क्या यह पूरा रडाउन है? मैं देख सकता हूं कि NinjectHttpModule रनटाइम पर लोड किया गया है, लेकिन कोई इंजेक्शन नहीं हो रहा है। क्या आप किसी भी कारण से ऐसा सोच सकते हैं?
रसमास

3
महान उदाहरण थैंक्स यह पेज / मास्टर पेज पर काम करता है लेकिन Asmx पर नहीं। मैं इसे Asmx पर कैसे काम कर सकता हूं? धन्यवाद।
लॉफोटॉग

1
@mreyeros सुनिश्चित करें कि आपके पास एक NinjectWeb.csहै App_Start। Ninject को इनिशियलाइज़ करने के लिए आपके कोड को इस फाइल में जाना होगा। यदि यह एक अलग फाइल में है (जैसे NinjectWebCommon.csयह काम नहीं करेगा)। यदि आप Ninject का उपयोग करके अन्य Ninject पैकेजों की तुलना में बाद में Ninject.Web स्थापित करते हैं तो यह हो सकता है।
नेफ्फा

12

वर्तमान में यहाँ उत्तर एक बग के कारण काम नहीं करता है । यहाँ @ जेसन के चरणों का एक संशोधित संस्करण है जिसे ग्राहक httpmodule का उपयोग करके पन्नों में इंजेक्ट किया जा सकता है और विशेषण वर्गों से विरासत में लेने की आवश्यकता के बिना नियंत्रित करता है।

  1. एक नया ASP.NET WebForms प्रोजेक्ट बनाएं
  2. Ninject.Web lib को जोड़ने के लिए NuGet का उपयोग करें
  3. App_Start / NinjectWebCommon.cs / RegisterServices विधि में अपने कस्टम बाइंडिंग को पंजीकृत करें
  4. InjectPageModule जोड़ें और NinjectWebCommon में पंजीकरण करें
  5. अपने पृष्ठों पर विशेषता इंजेक्शन का उपयोग करें

InjectPageModule.cs

 public class InjectPageModule : DisposableObject, IHttpModule
{
    public InjectPageModule(Func<IKernel> lazyKernel)
    {
        this.lazyKernel = lazyKernel;
    }

    public void Init(HttpApplication context)
    {
        this.lazyKernel().Inject(context);
        context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
    }

    private void OnPreRequestHandlerExecute(object sender, EventArgs e)
    {
        var currentPage = HttpContext.Current.Handler as Page;
        if (currentPage != null)
        {
            currentPage.InitComplete += OnPageInitComplete;
        }
    }

    private void OnPageInitComplete(object sender, EventArgs e)
    {
        var currentPage = (Page)sender;
        this.lazyKernel().Inject(currentPage);
        this.lazyKernel().Inject(currentPage.Master);
        foreach (Control c in GetControlTree(currentPage))
        {
            this.lazyKernel().Inject(c);
        }

    }

    private IEnumerable<Control> GetControlTree(Control root)
    {
        foreach (Control child in root.Controls)
        {
            yield return child;
            foreach (Control c in GetControlTree(child))
            {
                yield return c;
            }
        }
    }

    private readonly Func<IKernel> lazyKernel;
}

NinjectWebCommon / RegisterServices

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<IHttpModule>().To<InjectPageModule>();
        kernel.Bind<IAmAModel>().To<Model1>();

    } 

चूक

public partial class _Default : System.Web.UI.Page
{

    [Inject]
    public IAmAModel Model { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        System.Diagnostics.Trace.WriteLine(Model.ExecuteOperation());
    }
}

Site.Master

public partial class SiteMaster : System.Web.UI.MasterPage
{

    [Inject]
    public IAmAModel Model { get; set; }

    protected void Page_Load(object sender, EventArgs e)
    {
        System.Diagnostics.Trace.WriteLine("From master: " 
            + Model.ExecuteOperation());
    }
}

मॉडल

public interface IAmAModel
{
    string ExecuteOperation();         
}

public class Model1 : IAmAModel
{
    public string ExecuteOperation()
    {
        return "I am a model 1";
    }
}

public class Model2 : IAmAModel
{
    public string ExecuteOperation()
    {
        return "I am a model 2";
    }
}

आउटपुट विंडो से परिणाम

I am a model 1
From master: I am a model 1

4
कृपया ध्यान दें कि यह उन पृष्ठों के लिए विफल है, जिनमें मास्टर पृष्ठ नहीं है। मैंने इसके साथ NinjectWebCommon को संशोधित किया: if (currentPage.Master!=null) { this.lazyKernel().Inject(currentPage.Master); }
H.Wolper

1
इस दस्तावेज़ के लिए समय निकालने के लिए धन्यवाद। मुझे विरासत वेबफॉर्म प्रोजेक्ट के साथ काम करने में समान समस्या थी। धन्यवाद आपको यह मिल गया - समायोजित खदान के साथ-साथ Page_Init से पहले काम करने के लिए क्योंकि यह बहुत देर से बुलाया जा रहा था, लेकिन अन्यथा एकदम सही है। धन्यवाद @ अदम!
PoorbandTony

इस समाधान ने मेरे लिए कुछ वास्तव में यादृच्छिक मुद्दों का कारण बना। उदाहरण के लिए, OnCommand ईवेंट्स ने Rep थिएटर के भीतर लिंकबुटन पर चलना बंद कर दिया। हालांकि यह सभी कोड-पीछे की घटनाओं को नहीं तोड़ता था।
माइक कोल

8

मुझे लगता है कि यहाँ ASP.NET वेब फ़ॉर्म पर Ninject.Web को लागू करने के चरण दिए गए हैं।

  1. Global.asax पर NinjectHttpApplication लागू करें। कर्नेल के लिए, इसे NinjectModule लागू करके पास करें।
  2. कोड के पीछे प्रत्येक वेब फॉर्म पेज लोड घटना पर, Ninject.Web.PageBase को लागू करें। इसके साथ फ़िल्टर करें [Inject] के साथ इंस्टेंस क्लास जोड़ें।

अधिक विस्तृत उदाहरण के लिए, नीचे कुछ उपयोगी लिंक दिए गए हैं:

1. http://joeandcode.net/post/Ninject-2-with-WebForms-35

2. http://davidhayden.com/blog/dave/archive/2008/06/20/NinjectD dependencyInjectionASPNETWebPagesSample.aspx


1
यह माना जाता है कि आपने Ninject.Web एक्सटेंशन जोड़ दिया है, जो कि आपको करने की आवश्यकता है।
डेव थीबेन

7
@nellbryant उन दोनों लिंक अब मृत हो गए हैं।
बोगिन

joeandcode.net लिंक अब मृत हो गया है। संग्रहीत संस्करण यहाँ है: web.archive.org/web/20160324142135/http://joeandcode.net/post/…
क्रिस वॉल्श

4

Ninject.Web विस्तार पर एक नज़र है। यह आधारभूत संरचना https://github.com/ninject/ninject.web प्रदान करता है


5
मुझे पता है कि मुझे उदाहरण के लिए नेतृत्व करना चाहिए, लेकिन README को 0 बाइट्स होना चाहिए!
बारबेलिंक

@ रूबेन: मैं मानता हूं कि डीआईआर अपडेट करना सूची ए.टी.एम. पर उच्च पुरस्कार कार्यों में से एक है।
रेमो ग्लोर

2
यह प्राथमिकता के बारे में है और समुदाय से कितनी मदद मिलती है। पिछले वर्ष बहुत सारे दस्तावेज जोड़े गए थे। Ninject.Web के लिए नहीं क्योंकि मैं इसे अन्य विशेषताओं की तुलना में कम महत्वपूर्ण मानता हूं क्योंकि: a) WebForms अप्रचलित है - B के बजाय MVC का उपयोग करें) मैंने यह एक्सटेंशन नहीं लिखा है। बाकी सभी की तरह मुझे भी कोड से इस विस्तार के बारे में जानकारी लेनी होगी। ग) मैं खुद इसका उपयोग नहीं करता - ऐसे अन्य हैं जो स्वयं से बहुत बेहतर तरीके से लिख सकते हैं। लेकिन ऐसा लगता है कि यह उनमें से किसी के लिए महत्वपूर्ण नहीं है। मेरा खाली समय आपकी तरह सीमित है और इसलिए मैं सब कुछ नहीं कर सकता।
रेमो ग्लोर

6
@RyanW डाउनवॉटिंग सिर्फ गुमशुदा प्रलेखन के कारण वास्तव में मेरी प्रेरणा नहीं बढ़ाएगा या आपके लिए यह मुद्रा लिखने की प्राथमिकता नहीं बढ़ाएगा!
रेमो ग्लोर

1
@RyanW आप अपने विचारों को कहाँ प्राप्त करते हैं? मुझे एक साल पहले से मेरी घिनौनी टिप्पणी के बारे में बुरा लग रहा है, लेकिन क) यह एक उथल-पुथल के साथ था) यह व्यंग्यात्मक था, लेकिन व्हिस्की नहीं। कृपया पूरी तरह से वैध बिंदुओं का खंडन करें रेमो खिलौने बाहर फेंकने के लिए वरीयता देते हैं। BTW मुझे यकीन है कि एकता के पास भयानक प्रलेखन है और आपकी गली में अधिक हो सकता है। और nellbryant या Jor R के उत्तर को देखें और या तो उस के साथ गलती खोजने की कोशिश करें या इसका उपयोग खुद को रीडमी या नमूना लिखने के लिए करें।
बर्टेलिंक

0

स्टीव सैंडरसन (एप्रेस) द्वारा "प्रो ASP.NET MVC 2 फ्रेमवर्क, 2 संस्करण" पुस्तक की जाँच करें। लेखक डेटाबेस से जुड़ने के लिए निन्जेक्ट का उपयोग करता है। मुझे लगता है कि आप उदाहरणों का उपयोग कर सकते हैं और उन्हें अपनी आवश्यकताओं के अनुकूल बना सकते हैं।


हां, मेरे पास वह है जिसने मुझे उस प्रश्न को पूछने के लिए प्रेरित किया। यदि वेब एप्लिकेशन वेब फॉर्म है तो यह कैसे किया जाता है?
nellbryant

यह भी है कि मैं आमतौर पर इसके बारे में WebForms में कैसे जाता हूं। चाल आपको कर्नेल की गेट विधि का उपयोग करने की आवश्यकता है।
दीदीक्सिस

0
public IGoalsService_CRUD _context { get; set; }

_Context ऑब्जेक्ट को किसी तरह से शून्य करने के लिए सेट किया जा रहा है। बाकी सेटिंग्स निम्नलिखित हैं

public partial class CreateGoal : Page
{
    [Inject]
    public IGoalsService_CRUD _context { get; set; }
}

ग्लोबल फ़ाइल के लिए

protected override IKernel CreateKernel()
{
    IKernel kernel = new StandardKernel(new Bindings());
    return kernel;
}

public class Bindings : NinjectModule
{
    public override void Load()
    {
        Bind<goalsetterEntities>().To<goalsetterEntities>();
        Bind<IGoalsService_CRUD>().To<GoalsService_CRUD>();
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.