10

मैं प्रति ग्राहक आधार पर कोर उत्पाद के आसान अनुकूलन और विस्तार की अनुमति देने के बारे में कुछ सलाह ढूंढ रहा हूं। मुझे पता है कि यह शायद एक सवाल बहुत बड़ा है। हालांकि हमें वास्तव में कुछ विचारों को प्राप्त करने की आवश्यकता है जैसे कि हमें इस गलत का सेटअप मिल जाए, इससे हमें वर्षों तक समस्याएं हो सकती हैं। मेरे पास मौजूदा उत्पादों को अनुकूलित और विस्तारित करने में बहुत अधिक अनुभव नहीं है।प्रति ग्राहक आधार पर किसी उत्पाद के आसान अनुकूलन की अनुमति देने के लिए एक अच्छी समाधान संरचना क्या है?

हमारे पास एक मूल उत्पाद है जिसे हम आमतौर पर प्रति ग्राहक आधार पर bespoke करते हैं। हमने हाल ही में एक एमवीसी 3 फ्रंटएंड के साथ उत्पाद को सी # 4 में फिर से लिखा है। हम पुनर्संशोधित है और अब 3 परियोजनाओं कि समाधान रचना है: (। नाम स्थान - projectname.domain *) -

  • कोर डोमेन परियोजना (उपयोग के लिए एफई द्वारा) डोमेन मॉडल से मिलकर, डोमेन सेवा इंटरफेस आदि (भंडार इंटरफेस)
  • डोमेन बुनियादी ढांचा परियोजना (नाम स्थान -projectname.infrastructure *) -। कि डोमेन सेवा-एफई प्रसंग, भंडार कार्यान्वयन, फ़ाइल अपलोड/डाउनलोड इंटरफ़ेस कार्यान्वयन आदि
  • MVC3 (नाम स्थान को लागू करता है -। projectname.web *) -प्रोजेक्ट जिसमें नियंत्रक, व्यूमोडेल, सीएसएस, सामग्री, स्क्रिप्ट आदि शामिल हैं। इसमें आईओसी (निनजेक्ट) परियोजना के लिए डी को संभालने में भी है।

यह समाधान एक स्टैंडअलोन उत्पाद के रूप में ठीक काम करता है। हमारी समस्या प्रति ग्राहक आधार पर उत्पाद को विस्तार और अनुकूलित कर रही है। ब्रांडेड सीएसएस और स्टाइल के साथ आमतौर पर हमारे ग्राहक कोर उत्पाद संस्करण को बहुत जल्दी (आमतौर पर अनुबंध पर हस्ताक्षर करने के कुछ दिनों के भीतर) चाहते हैं। हालांकि 70% ग्राहक फिर अनुकूलन चाहते हैं कि यह किस तरह से काम करता है। कुछ अनुकूलन छोटे मॉडल जैसे डोमेन मॉडल, व्यूमोडेल और व्यू आदि जैसे छोटे हैं। अन्य अधिक महत्वपूर्ण हैं और पूरी तरह से नए डोमेन मॉडल और नियंत्रक आदि की आवश्यकता है

कुछ अनुकूलन सभी ग्राहकों के लिए उपयोगी प्रतीत होता है, इसलिए समय-समय पर हम चाहेंगे उन्हें अनुकूलन से बदलने और उन्हें कोर में जोड़ने के लिए।

हम वर्तमान में टीएफएस में स्रोत कोड संग्रहीत कर रहे हैं। एक प्रोजेक्ट शुरू करने के लिए हम आमतौर पर स्रोत को एक नई टीम प्रोजेक्ट में कॉपी करते हैं। क्लाइंट नाम को प्रतिबिंबित करने के लिए नामस्थान बदलें और मूल भागों को अनुकूलित करना प्रारंभ करें और फिर Azure पर तैनात करें। यह स्पष्ट रूप से पूरी तरह से डुप्लीकेट कोड बेस में परिणाम देता है और मुझे यकीन है कि इसके बारे में जाने का सही तरीका नहीं है। मुझे लगता है कि हमें शायद ऐसा कुछ होना चाहिए जो मूल सुविधाओं को प्रदान करता हो और जहां आवश्यक हो, ओवरराइड/ओवरराइड करता है। हालांकि मुझे सच में यकीन नहीं है कि इस बारे में कैसे जाना है।

तो मैं सबसे अच्छा परियोजना विन्यास पर कोई सलाह है कि अनुमति होगी रहा हूँ:

  • कोड का तेजी से तैनाती - इतना आसान लिए एक नए ग्राहक से शुरू करने के लिए ब्रांडिंग/मामूली परिवर्तन के लिए अनुमति
  • रोकें कॉपी करने और कोड की चिपकाने के लिए की जरूरत
  • जितना संभव हो उतना DI के
  • उपयोग यह शिथिल युग्मित
  • ग्राहक आधार प्रति एक पर कोड का bespoking के लिए अनुमति दें रखने के लिए
  • एक भी जगह में कोर उत्पाद का विस्तार करने और सभी ग्राहकों है कि कार्यक्षमता हासिल अगर हम कोर और की नवीनतम संस्करण प्राप्त करने की क्षमता फिर से तैनात

कोई मदद/सलाह बहुत सराहना कर रहा है। अधिक जानकारी जोड़ने में खुशी है कि कोई भी सोचने में मदद करेगा।

+0

5 परियोजनाओं के लिए प्रति क्लाइंट की शाखा बनाने की कोशिश करने के बाद हमने छोड़ दिया। हमने अब इसे एक ऐसे उत्पाद के रूप में लिखा है जो क्लाइंट कॉन्फ़िगरेशन के आधार पर इसे एक साथ खींचने के लिए MEF और DI का उपयोग करता है। इसके अलावा इसका मतलब है कि हम इसे एक वेब होस्ट पर तैनात कर सकते हैं और यह बेहतर स्केल करता है। – GraemeMiller

+0

बहु-किरायेदारी पर इसे देखें जो बहुत अधिक स्थिति को कवर करता है http://codeofrob.com/entries/multi-tenancy-in-asp.net-mvc---ddd8-video.html – GraemeMiller

उत्तर

4

I just worried that with 30 or 40 versions (most of which aren't that different) branching was adding complexity.


+1 महान सवाल है, इसकी एक व्यापारिक निर्णय के अधिक आप बनाने के लिए होगा:

मैं एक साफ कोड आधार जहां रखरखाव आसान है करना चाहते हैं और सुविधाओं और सुधारों मिल हमारे सभी ग्राहकों

या मैं एक codebase के उदाहरण की अधिकता को विभाजित करना चाहते हैं के लिए जल्दी से बाहर लुढ़का, छोटे तोड़ मरोड़ के साथ प्रत्येक है कि हार्ड (संपादित करें: जब तक आपके एक एएलएम एमवीपी जो कर सकते हैं "unbrand" बातें) को एक टीआर में विलय UNK।


मैं लगभग प्रत्येक भाग को @Nockawa IMHO छोड़कर उल्लेख के साथ सहमत स्थानापन्न शाखाओं के साथ अपने कोड वास्तुकला का विस्तार नहीं है।

निश्चित रूप से शाखा/ट्रंक रणनीति का उपयोग करें, लेकिन जैसा कि आपने बताया है कि बहुत सी शाखाएं quickly रोल-आउट साइट की विस्तृत सुविधाओं और परियोजना-व्यापी निरंतर एकीकरण में बाधा डालती हैं। यदि आप प्रतिलिपि/चिपकने वाली शाखाओं की संख्या को सीमित करना चाहते हैं।

  • मॉड्यूल/प्लग इन, इंटरफेस और डि लक्ष्य पर सही है:

    एक कोडिंग यहाँ समाधान के संदर्भ में आप के लिए क्या मेरा मानना ​​है कि ढूंढ रहे हैं!

  • पाने कस्टम कक्षाएं बंद आधार हैं (प्रति ग्राहक डीएसएल विस्तार, Assembly.Load())
  • कस्टम रिपोर्टिंग समाधान
  • स्प्रेडशीट के साथ पृष्ठ (नए पृष्ठों के बजाय कस्टम अनुरोधों का एक बहुत कुछ रिपोर्टों हो सकता है) (hehe मैं जानता हूँ कि - लेकिन काफी मजेदार यह काम करता है)

मॉड्यूल/प्लगइन बिंदु के महान उदाहरण सीएमएस के इस तरह के रूप DotNetNuke या एंथनी कर रहे हैं!। फेसबुक के ऐड-इन आर्किटेक्चर, ऑडियो और वीडियो संपादन के लिए प्लगइन, 3 डी मॉडलिंग ऐप्स (जैसे 3 डीमैक्स) और गेम जो आपको अपना खुद का स्तर बनाने देते हैं, देखकर अन्य विचार प्राप्त किए जा सकते हैं।

आदर्श समाधान सीएसएस (त्वचा) एक व्यवस्थापक ऐप है कि आप अपने मॉड्यूल चुन सकते हैं (DLL का), दर्जी, स्क्रिप्ट डीबी होगा, और ऑटो को तैनात Azure तक समाधान। इस लक्ष्य को प्राप्त करने के लिए प्लगइन अधिक समझ में आएगा, कोडेबेस को विभाजित नहीं किया जाएगा। साथ ही जब मॉड्यूल में वृद्धि की जाती है - तो आप इसे अपने सभी क्लाइंट में रोल कर सकते हैं।

आप उपयोगकर्ता नियंत्रण, व्युत्पन्न कक्षाओं और फ़ंक्शन ओवरराइड के साथ डोमेन मॉडल, व्यूमोडेल और दृश्य आदि पर अतिरिक्त गुणों जैसे आसानी से छोटे अनुकूलन कर सकते हैं।

यह वास्तव में सामान्य रूप से करें, एक ग्राहक का कहना है कि मैं एक लेबल चाहता हूं जो सिस्टम में हर किसी की उम्र का मिलान करे, int SumOfField(string dBFieldName, string whereClause) नामक एक फ़ंक्शन बनाएं और फिर उस ग्राहक साइट के पास एक लेबल है जो फ़ंक्शन से जुड़ता है। फिर एक और ग्राहक चाहता है कि एक कर्मचारी ग्राहक द्वारा उत्पाद खरीद की संख्या को गिनने के लिए चाहता है, आप इसका पुन: उपयोग कर सकते हैं: SumOfField ("product.itemCount", "clientID = 1")।

अधिक महत्वपूर्ण परिवर्तन जो पूरी तरह से नए डोमेन मॉडल और नियंत्रक आदि की आवश्यकता है प्लग-इन आर्किटेक्चर में फिट होंगे। एक उदाहरण हो सकता है कि किसी ग्राहक को दूसरे पता फ़ील्ड की आवश्यकता हो, तो आप किसी भी पेज पर प्लग-इन होने के लिए अपने वर्तमान पता उपयोगकर्ता-नियंत्रण को ट्वीक कर देंगे, इसमें सेटिंग्स को यह पता चल जाएगा कि कौन सी डीबी टेबल और फ़ील्ड सीआरयूडी ऑपरेशंस में अपने इंटरफ़ेस को कार्यान्वित कर सकती हैं ।

कार्यक्षमता 30-40 शाखाओं में ग्राहक प्रति अनुकूलित है, तो रख-रखाव की इतनी मेहनत मैं महसूस पाने के रूप में हो जाएगा आप अभ्यस्त उन्हें एक साथ (आसानी से) विलय करने में सक्षम हो। यदि कोई मौका है तो यह वास्तव में बड़ा होगा, आप 275 शाखाओं का प्रबंधन नहीं करना चाहते हैं। हालांकि, यदि विशिष्ट है तो आपको प्रत्येक ग्राहक और "उपयोगकर्ता अपने स्वयं के पृष्ठों को डिज़ाइन नहीं कर सकते" के लिए उपयोगकर्ता-नियंत्रण स्तर पर जाना होगा, उसके बाद फ्रंट-एंड के लिए नोकावा की शाखा रणनीति पूरी तरह से उचित है।

+1

ग्रेट उत्तर भी। मैं उन दोनों दृष्टिकोणों को लेने जा रहा हूं जो मुझे लगता है। मैं ऑर्चर्ड को एप्लिकेशन मॉड्यूलर बनाने के तरीके पर प्रेरणा के लिए देख रहा हूं। मैं उस पर एक और सवाल लिखने जा रहा हूं और शायद इस पर एक बक्षीस डालूंगा।प्रारंभ में हालांकि मैं ब्रांचिंग पर ध्यान केंद्रित कर रहा हूं क्योंकि यह शुरू करने का सबसे आसान स्थान है क्योंकि हमारे पास केवल कुछ क्लाइंट नए कोड बेस पर जा रहे हैं। एक बार जब मैं देखता हूं कि विचलन कहां हो रहा है, तो मैं उन हिस्सों को मॉड्यूल में परिवर्तित करने के लिए देखता हूं और फिर उन्हें शाखा बना देता हूं। – GraemeMiller

+0

ब्रांडेड दृष्टिकोण के साथ 5 ग्राहकों के बाद हमने छोड़ दिया। यह एक दु: स्वप्न था। हमारा मूल उत्पाद लगातार बदल रहा था और निरंतर विलय की आवश्यकता थी। हम डीआई का उपयोग करके मॉड्यूलर दृष्टिकोण को लागू कर रहे हैं और एमईएफ का उपयोग भी कर रहे हैं। हम इसे तैनात कर रहे हैं यह एक एकल उत्पाद है और विन्यास को सूचित करने के लिए कि कौन से मॉड्यूल/अनुकूलन शामिल हैं। यह बहुत आसान था। बस डिजाइन के चारों ओर थोड़ा और विचार की आवश्यकता है। – GraemeMiller

8

मैं पूरी तरह से इस का जवाब नहीं है, लेकिन यहाँ कुछ सलाह:

  1. अपने कोड की नकल न करें, कभी, जो भी कारण है।
  2. किसी दिए गए क्लाइंट संस्करण की पहचान करने के लिए नामस्थान का नाम न बदलें। इसके लिए शाखाओं और निरंतर एकीकरण का प्रयोग करें।
  3. निम्नलिखित जैसे शाखाकरण मॉडल चुनें: "मुख्य" नामक मूल शाखा, फिर अपने उत्पाद के मुख्य प्रति प्रमुख संस्करण से एक शाखा बनाएं, फिर प्रति ग्राहक एक शाखा बनाएं। जब आप कुछ विकसित करते हैं, तो शुरुआत से लक्ष्य करें कि आप जो भी कर रहे हैं उसके आधार पर आप किस शाखा में विकास करेंगे (क्लाइंट विशिष्ट सुविधा क्लाइंट शाखा में जाएगी, संस्करण शाखा या क्लाइंट शाखा में वैश्विक संस्करण यदि आप प्रोटोटाइप करना चाहते हैं यह पहले, आदि)
  4. उन कार्यों को ट्रैक करने के लिए वर्क आइटम पर भरोसा करने के लिए सबसे अच्छा प्रयास करें, जिन्हें आप जानते हैं कि शाखाओं में विलय को आसान बनाने के लिए किस शाखा को लागू किया गया है।

आपके लिए सही शाखा को लक्षित करना सबसे महत्वपूर्ण बात है, आपको "अवसर में क्या करना है" के कुछ कठिन नियमों को परिभाषित करने की आवश्यकता नहीं है, लेकिन लगातार बने रहने की कोशिश करें।

मैं 75 से अधिक संस्करणों के साथ एक बड़ा 10 साल प्रोजेक्ट पर काम किया है और क्या हम आम तौर पर किया था:

  • अगला प्रमुख संस्करण: मुख्य से एक नई शाखा, देव अंदर
  • अगला नाबालिग बनाने संस्करण: वर्तमान प्रमुख शाखा में देव, अपनी शाखा के अंदर प्रत्येक मामूली संस्करणों को चिह्नित करने के लिए लेबल का उपयोग करें।
  • कुछ जटिल कार्यात्मक सुविधाओं को क्लाइंट की शाखा में विकसित किया गया था, इसके लिए पूछा गया था, फिर संस्करण शाखा में एकीकृत किया गया जब हम "अनबन्धित" में सफल हुए।
  • ग्राहक शाखा में बग फिक्स, फिर आवश्यक होने पर अन्य शाखाओं में रिपोर्ट किया गया। (आपको उस के लिए वर्क आइटम का उपयोग करना होगा या आप आसानी से खो जाएंगे)।

ऐसा नहीं है कि मेरे पर ले, दूसरे को देखने का अलग बिंदु हो सकता है, मैं एक बहुत काम मद पर कोड है, जो वितरण और कोड की रिपोर्टिंग के लिए एक बहुत मदद की पता लगाने की क्षमता के लिए भरोसा किया है।

संपादित

ठीक है, मैं शाखाओं के बारे में कुछ विचार/प्रतिक्रिया जोड़ें: शाखाओं और लेबल:

सॉफ्टवेयर विन्यास प्रबंधन (SCM) में आप दो सुविधाओं versionning के लिए आप में मदद करने के लिए है। हर एक को बेहतर नहीं है और न ही अन्य की तुलना में सबसे खराब है, यह इस पर निर्भर करता है कि तुम क्या जरूरत है:

  1. एक लेबल समय में एक बिंदु चिह्नित करने के लिए प्रयोग किया जाता है, एक लेबल का उपयोग कर, आप बाद में उस पर वापस जाने के लिए सक्षम होने के लिए यदि आवश्यक हो तो बिंदु।
  2. एक शाखा का उपयोग पर एक ही समय में पर काम करने में सक्षम होने के लिए आपके कोड को "डुप्लिकेट" करने के लिए किया जाता है।

तो शाखाओं का उपयोग केवल उस पर निर्भर करता है कि आप क्या करने में सक्षम होना चाहते हैं। यदि आपको एक ही समय में एक से अधिक अलग-अलग संस्करण (प्रति ग्राहक एक कहें) काम करना है: शाखाओं का उपयोग करने से निपटने का कोई और तरीका नहीं है।

आप तय करने के लिए क्या एक नई शाखा हो जाएगा या क्या के लिए एक लेबल द्वारा चिह्नित किया जाएगा शाखाओं की संख्या सीमित करने के लिए: ग्राहक विशिष्ट संस्करण, मेजर संस्करण, लघु संस्करण, सर्विस पैक, आदि

का उपयोग करना क्लाइंट संस्करणों के लिए शाखाएं कोई ब्रेनर नहीं लगती हैं। प्रत्येक प्रमुख संस्करण के लिए एक शाखा का उपयोग करना आपके लिए सबसे कठिन विकल्प हो सकता है। यदि आप सभी प्रमुख संस्करणों के लिए केवल एक शाखा का उपयोग करना चुनते हैं, तो आपके पास एक ही समय में विभिन्न प्रमुख संस्करणों पर काम करने की लचीलापन नहीं होगी, लेकिन आपकी शाखाओं की संख्या सबसे कम संभव होगी।

अंत में, जेमरी थॉम्पसन का एक अच्छा बिंदु है जब वह कहता है कि आपका सभी कोड ग्राहक निर्भर नहीं होना चाहिए, कुछ पुस्तकालय (आमतौर पर निम्नतम स्तर वाले) हैं जिन्हें प्रति ग्राहक अनुकूलित नहीं किया जाना चाहिए। हम आमतौर पर फ्रेमवर्क, क्रॉस-कटिंग, निम्न स्तरीय सेवा पुस्तकालयों के लिए अलग शाखा पेड़ (जो प्रति क्लाइंट नहीं है) का उपयोग कर रहे हैं। फिर प्रति क्लाइंट संस्करण परियोजनाओं में इन परियोजनाओं का संदर्भ लें।

आपके लिए मेरी सलाह इन पुस्तकालयों के लिए Nuget का उपयोग कर रही है और उनके लिए nuget पैकेज बना रही है, क्योंकि यह संस्करणबद्ध निर्भरताओं को परिभाषित करने का सबसे अच्छा तरीका है। एक Nuget पैकेज को परिभाषित करना वास्तव में आसान है, साथ ही स्थानीय Nuget सर्वर स्थापित करना भी आसान है।

+0

आपकी प्रतिक्रिया के लिए धन्यवाद। मैं शाखा बनाने की भावना देख सकता हूं। यदि मैं क्लाइंट संस्करण की पहचान करने के लिए नेमस्पेस नहीं बदलता तो यह इसे बहुत आसान बना देगा। किसी कारण से मैंने अभी एक कोर चित्रित किया है जो विरासत में प्राप्त संस्करणों को बेदखल करता है। यह अच्छी तरह से हो सकता है कि कोर में कस्टमाइज़ेशन को सिर्फ ब्रांचिंग और पुन: एकीकृत करना सिर्फ अधिक समझ में आता है। मुझे बस चिंता है कि 30 या 40 संस्करणों (जिनमें से अधिकांश अलग नहीं हैं) शाखाकरण जटिलता जोड़ रहा था। – GraemeMiller

+2

शाखाओं को टीएफएस में उतना ही खर्च नहीं होता है, इसलिए आपकी एकमात्र चिंता यह है कि मात्रा को कुशलता से कैसे प्रबंधित किया जाए। – Nock

+1

+1 एक अच्छा प्रश्न के लिए अच्छा सारांश –

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

  • कोई संबंधित समस्या नहीं^_^