سؤال

أنا بصدد إنشاء موفر عضوية مخصص لموقع ASP.NET MVC. يتم إنشاء المزود كطبقة منفصلة كجزء من مكتبة أكبر. هناك حاجة إلى أن يكون متجر البيانات الخلفي مرنًا لأنه يمكن أن يكون ملف XML أو قاعدة بيانات SQL. كانت فكرتي الأولية هي إنشاء واجهة لمخزن البيانات وحقن هذا في مزود باستخدام حقن التبعية.

تتمثل النتيجة النهائية في أنه يمكن للمطور أن يرث واجهة متجر البيانات وتوفير الطرق المطلوبة لتحديث البيانات ، والتي سيتم استخدامها بعد ذلك من قبل مقدمي العضوية المخصصة.

ولكن من خلال افتقاري إلى المهارة ، لا يمكنني معرفة كيفية ضخ الفصل في مزود العضوية عند إضافته إلى الموقع؟ ما الذي يجب القيام به لربط متجر البيانات بالمزود؟ ما هي أبسط طريقة لتمكين هذا في الموقع؟

هل كانت مفيدة؟

المحلول

إذا كنت تقوم بتكوين مقدمي العضوية المخصصين عبرu003Cmembership> العنصر في ملف web.config ، ثم يمكنني رؤية المشكلات التي ستواجهها مع حقن التبعية.

يتم بناء مقدمي الخدمات وإدارتهم من خلال الإطار ، وليس هناك فرصة لك لاعتراض هذا البناء لتوفير حقن تبعية إضافية ل IDataStore واجهه المستخدم.

إذا كان افتراضي صحيحًا ، فإن ما يمكنك فعله هو تجاوز Initialize() الطريقة في مزودك المخصص ، وقم بحقن التبعية هناك. يمكن أن يكون لديك إعداد اسم/قيمة مخصص في تكوين المزود الذي يشير إلى نوع ينفذ IDataStore, ، الذي يتم تمريره كجزء من قاموس إلى Initialize() طريقة.

بعد ذلك ، تقوم بتنشيط مثيل لنوع متجر البيانات وتعيينه على الخاصية المناسبة:

public class MyMembershipProvider : MembershipProvider
{
    public IDataStore DataStore
    {
        get;
        set;
    }

    public override Initialize(string name, NameValueCollection config)
    {
        var dataStoreType = config["dataStoreProvider"];
        if (!String.IsNullOrEmpty(dataStoreType))
        {
            var type = Type.GetType(dataStoreType);
            DataStore = (IDataStore) Activator.CreateInstance(type);
        }
    }
}

Initialize() سيتم استدعاؤه من قبل الإطار بعد أن يبني مثيلًا لمزودك ، بحيث يكون هذا هو المكان المثالي للقيام بأي عمل إضافي مثل هذا.

للاختبار سيناريوهات ، يمكنك فقط تعيين خاصية متجر البيانات على مثيل المزود نفسه ، حيث ستقوم ببنائها مباشرة في اختباراتك.

نصائح أخرى

أليس هذا أفضل؟ أنا استخدمه مع MVC3 و Ninject. يكفي إضافة خاصية إلى فئة مزود العضوية المخصصة. تذكر أن تضيف "استخدام system.web.mvc ؛" في الأعلى.

public IRepository Repository
{
    get
    {
        return DependencyResolver.Current.GetService<IRepository>();
    }
}

إن أبسط طريقة للقيام بحقن التبعية الذي رأيته (وفي الواقع الوحيدة التي استخدمتها حتى الآن ...) هي أن يكون لديك مُنشئ لفصلك التابع ، ويأخذ الواجهة كمعلمة ، وتعيينها إلى خاص ميدان. إذا كنت تريد ، يمكنك أيضًا إضافة مُنشئ "افتراضي" ، وهو سلاسل إلى الأولى ذات القيمة الافتراضية.

مبسطة ، سيبدو مثل هذا:

public class DependentClass
{
    private IDataStore _store;

    // Use this constructor when you want strict control of the implementation
    public DependentClass(IDataStore store)
    {
         this._store = store;
    }

    // Use this constructor when you don't want to create an IDataStore instance
    // manually every time you create a DependentClass instance
    public DependentClass() : this(new DefaultDataStore()) { }
}

يُطلق على هذا المفهوم اسم "Constructor Chaining" ، وهناك الكثير من المقالات على الويب حول كيفية القيام بذلك. وجدت هذا البرنامج التعليمي توضيح جدا لنمط DI.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top