يبدو إيتيراتيهلبر مبالغة. الزائد الذي don39t تأخذ مؤشر ينتهي به القيام الكثير المزيد من العمل الإضافي (تحويل رد على لامدا الذي يأخذ مؤشر، والحفاظ على العد الذي لم يستخدم). وأنا أفهم إعادة استخدام 39s، ولكن it39s الحل فقط باستخدام فورلوب على أي حال لذلك ينبغي أن تكون فعالة. نداش كاميرون ماكفارلاند ديك 29 08 في 23:20 إيف حاولت بعض الاختلافات على هذا، وأنا أعود إلى هذا الحل الرجال. مرة أخرى، هذا هو الحل إلسس شخص ما. ولكن إيف تجميع التعليمات البرمجية في مكتبة صغيرة، واستخدامها بشكل منتظم إلى حد ما. أنا ذاهب لصق رمزه هنا، لفرصة قبالة أن موقعه (بلوق) يتوقف عن الوجود في مرحلة ما في المستقبل. (ثيرس شيء أسوأ من رؤية وظيفة تقول هنا هو الجواب بالضبط تحتاج، انقر، ورل الميت.) أجاب 17 17 في 14: 10I ركض مؤخرا أفول من هذا واستغرق مني بعض الوقت للعمل لماذا. تبين حقيقة أنني كنت بناء الاستعلام الخاص بي في أجزاء باستخدام إينوميرابل يتم استرداد السجلات 500k يعني (بطيئة) ثم تجميعها في الذاكرة. غيرت لاستخدام إكيريابل في حين بناء الاستعلام، تم تنفيذ المجموعة من قبل الملقم وأنا حصلت فقط على نصف عشرات من التهم كما كنت أتوقع. نداش ديف داونز قد 20 10 في 18:26 أود فقط أن أعرب عن مدى سهولة إجابتك قراءة. قرأت ثلاث مقالات على جوجل قبل أن وجدت الخاص بك فهمها بسهولة، تفسير السوبر بسيطة من الاختلافات. شكرا لك 1 نداش شيف جان 13 11 في 17:24 سبب آخر لتفضل إينوميرابل ل إكيريابل هو أن ليس كل عمليات لينق معتمدة من قبل جميع مقدمي لينق. حتى طالما كنت تعرف ما you39re القيام به، يمكنك استخدام المتصاعدة لدفع أكبر قدر من الاستعلام لمزود لينق (LINQ2SQL، إف، نهيبرنات، مونغودب الخ). ولكن إذا كنت ترك التعليمات البرمجية الأخرى تفعل ما تريد مع إكيريابل you39ll في نهاية المطاف في ورطة لأن بعض التعليمات البرمجية العميل في مكان ما استخدمت عملية غير معتمد. وأوافق على التوصية بعدم الإفراج عن المستوطن الذي كان يخزن المستودع أو الطبقة المكافئة. نداش أفيش 2 فبراير 14 في 19:19 أعلى إجابة جيدة ولكنها لا تذكر أشجار التعبير التي تفسر كيف تختلف واجهات اثنين. في الأساس، هناك مجموعتان متطابقتان من ملحقات لينق. حيث ()، سوم ()، كونت ()، فيرستوردفولت ()، إلخ كل إصدارين: واحد يقبل الوظائف وواحد يقبل التعابير. إينوميرابل التوقيع على النسخة هو: حيث (فونلكتوستومر، بولغت المسند) توقيع نسخة إكيريابل هو: حيث (إكسبريسيونلتفونكلتكوستومر، بولغتغ المسند) ربما كنت تستخدم كلا من دون أن يدرك ذلك لأن كلا تسمى باستخدام بناء جملة متطابقة: على سبيل المثال. حيث يعمل (x غ x. City لتسيتيغت) على كل من إينوميرابل و إكيريابل عند استخدام حيث () على مجموعة إينوميرابل، مترجم يمر الدالة المترجمة إلى أين () عند استخدام حيث () على مجموعة لا يصدق، مترجم يمر تعبير شجرة إلى أين (). شجرة التعبير هي مثل نظام الانعكاس ولكن للشفرة. يقوم المترجم بتحويل التعليمات البرمجية إلى بنية بيانات تصف ما تفعله الشفرة بتنسيق يسهل هضمه. لماذا عناء مع هذا الشيء شجرة التعبير أريد فقط حيث () لتصفية البيانات الخاصة بي. السبب الرئيسي هو أن كل من إف و Linq2SQL أورمز يمكن تحويل الأشجار التعبير مباشرة إلى سكل حيث التعليمات البرمجية الخاصة بك سوف تنفذ أسرع بكثير. أوه، هذا يبدو وكأنه دفعة أداء مجانية، يجب أن استخدام أسكريابل () في كل مكان في هذه الحالة لا إكوريابل مفيد فقط إذا كان مزود البيانات الأساسي يمكن أن تفعل شيئا معها. تحويل شيء مثل قائمة العادية ل إكيريابل لن تعطيك أي فائدة. وكلاهما سوف تعطيك التنفيذ المؤجل، نعم. أما الذي يفضل على الآخر، فإنه يعتمد على ما هو مصدر البيانات الأساسي الخاص بك هو. سيؤدي إرجاع إينوميرابل تلقائيا إلى فرض وقت التشغيل لاستخدام لينق إلى كائنات لاستعلام مجموعتك. إرجاع إكيريابل (الذي ينفذ إينوميرابل، بالمناسبة) يوفر وظيفة إضافية لترجمة الاستعلام الخاص بك إلى شيء قد تؤدي بشكل أفضل على المصدر الأساسي (لينق ل سكل، لينق ل شمل، الخ). نعم، كلاهما استخدام التنفيذ المؤجل. يتيح توضيح الفرق باستخدام ملف تعريف سكل سيرفر. عندما نقوم بتشغيل التعليمات البرمجية التالية: في ملف تعريف سكل سيرفر نجد أمر يساوي: يستغرق حوالي 90 ثانية لتشغيل هذا الكود من التعليمات البرمجية ضد جدول ويبلوغ الذي يحتوي على 1 مليون سجل. لذلك، يتم تحميل كافة سجلات الجدول في الذاكرة ككائنات، ثم مع كل. Where () سيكون فلتر آخر في الذاكرة ضد هذه الكائنات. عندما نستخدم إكوريابل بدلا من إينوميرابل في المثال أعلاه (السطر الثاني): في ملف تعريف سكل سيرفر نجد أمر يساوي: يستغرق تقريبا أربع ثوان لتشغيل هذه الكتلة البرمجية باستخدام إكوريابل. إكيريابل يحتوي على خاصية تسمى تعبير الذي يخزن تعبير شجرة الذي يبدأ يجري إنشاؤه عندما استخدمنا النتيجة في مثالنا (وهو ما يسمى التنفيذ المؤجل)، وفي نهاية هذا التعبير سيتم تحويلها إلى استعلام سكل لتشغيل على مشغل قاعدة البيانات . أجاب 8 يونيو 14 في 1:11 بشكل عام أود أن أوصي بما يلي: للعودة إكيريابللت إذا كنت ترغب في تمكين المطور باستخدام الأسلوب الخاص بك لصقل الاستعلام الذي يعود قبل التنفيذ. إذا كنت ترغب في نقل مجرد مجموعة من الكائنات لتعداد أكثر، فقط تأخذ إينوميرابل. تخيل أن متقن كما هو ما هو، استعلام للبيانات (التي يمكنك صقل إذا كنت تريد) إن إينوميرابل هو مجموعة من الكائنات (التي تم تلقيها بالفعل أو تم إنشاؤها) التي يمكنك تعداد. الرد أفاتار أبر 11 12 في 13:09 كوتكان تعداد، لا كوتكان IEnumerable. quot نداش كيسي 12 فبراير 14 في 18:23 هناك بلوق وظيفة مع موجز شفرة المصدر عينة حول كيفية إساءة استخدام إنوميرابللتغ يمكن أن تؤثر بشكل كبير على أداء الاستعلام لينق: الكيان الإطار : إكيريابل مقابل إينوميرابل. إذا كنا نبحث أعمق وننظر في المصادر، يمكننا أن نرى أن هناك طرق تمديد مختلفة بوضوح هي بيرفوميد ل إينوميرابللتغت: أول واحد يعود التكرار لا حصر لها، والثاني يخلق الاستعلام من خلال مزود الاستعلام، المحدد في مصدر إكيريابل. وقد قيل الكثير في السابق، ولكن العودة إلى الجذور، بطريقة أكثر تقنية: إينوميرابل هو عبارة عن مجموعة من الأشياء في الذاكرة التي يمكنك تعداد - تسلسل في الذاكرة التي تجعل من الممكن لتكرار من خلال (يجعل من السهل وسيلة ل داخل حلقة فوريش، على الرغم من أنك يمكن أن تذهب مع إينوميراتور فقط). يقيمون في الذاكرة كما هو. أكيريابل هي شجرة التعبير التي سوف تترجم إلى شيء آخر في مرحلة ما مع القدرة على تعداد على النتيجة النهائية. أعتقد أن هذا هو ما يخلط معظم الناس. ومن الواضح أن لها دلالات مختلفة. يمثل إكوريابل شجرة تعبير (استعلام، ببساطة) سيتم ترجمتها إلى شيء آخر من قبل موفر الاستعلام الأساسي بمجرد أن يتم استدعاء واجهات برمجة التطبيقات الإصدار، مثل لينك الدالات المجمعة (مجموع، عد، الخ) أو توليستاراي، قاموس. . و كيريابل الكائنات أيضا تنفيذ إينوميرابل. إينوميرابللتغ بحيث إذا كانت تمثل استعلام نتيجة هذا الاستعلام يمكن تكرار. وهذا يعني لا يصدق لا يجب أن تكون الاستعلامات فقط. المصطلح الصحيح هو أشجار التعبير. الآن كيف يتم تنفيذ هذه التعبيرات وما يتجهون إليه هو كل ما يصل إلى ما يسمى مقدمي الاستعلام (منفذي التعبير يمكننا أن نفكر فيهم). في عالم إطار الكيان (وهو أن باطني مزود مصدر البيانات الأساسية، أو مزود الاستعلام) يتم ترجمة التعبيرات القابلة للتعبير إلى استعلامات سكل T الأصلية. نهيبرنات يفعل أشياء مماثلة معهم. يمكنك كتابة واحد الخاص بك بعد المفاهيم وصفها بشكل جيد جدا في لينق: بناء وصلة موفر إكيريابل، على سبيل المثال، وكنت قد ترغب في الحصول على أبي الاستعلام مخصص لخدمة مزود مخزن المنتج الخاص بك. حتى في الأساس، يتم الحصول على الأشياء أكويريبل شيدت على طول الطريق حتى نقوم بإطلاق سراح لهم صراحة ونقول النظام لإعادة كتابة لهم في سكل أو أيا كان ويرسل أسفل سلسلة التنفيذ للمعالجة فصاعدا. كما لو أن التنفيذ المؤجل ميزة لينغ لتعليق مخطط شجرة التعبير في الذاكرة وإرسالها إلى التنفيذ فقط عند الطلب، كلما يتم استدعاء أبيس معينة ضد تسلسل (نفس العدد، تواليست، الخ). الاستخدام السليم لكلا يعتمد اعتمادا كبيرا على المهام التي تواجهها لحالة محددة. لنمط مستودع معروفة أنا شخصيا اختيار العودة إليست. وهذا هو إينوميرابل على قوائم (المفهرسين وما شابه ذلك). لذلك هو نصيحتي لاستخدام إكيريابل فقط داخل المستودعات و إينوميرابل في أي مكان آخر في التعليمات البرمجية. لا أقول عن مخاوف القابلية للاختبار التي تتعطل تتعطل وتدمر فصل مبدأ المخاوف. إذا قمت بإرجاع تعبير من داخل المستودعات قد تلعب المستهلكين مع طبقة استمرار كما يرغبون. إضافة قليلا إلى الفوضى :) (من مناقشة في التعليقات)) لا شيء منهم هي الأشياء في الذاكرة لأنها ليست أنواع حقيقية في حد ذاتها، فهي علامات من نوع - إذا كنت تريد أن تذهب عميقا. ولكن من المنطقي (وهذا هو السبب حتى مسن وضعه بهذه الطريقة) للتفكير في إنوميراتابلز كما في مجموعات الذاكرة في حين إكيريابلز كأشجار التعبير. النقطة هي أن واجهة إكيريابل ترث واجهة إينوميرابل بحيث إذا كان يمثل استعلام، يمكن تعداد نتائج هذا الاستعلام. ويؤدي التعداد إلى تنفيذ شجرة التعبير المرتبطة بكائن قابل للتكرار. لذلك، في الواقع، كنت غير قادر حقا استدعاء أي عضو إينوميرابل دون وجود الكائن في الذاكرة. وسوف تحصل في هناك إذا كنت تفعل، على أي حال، إذا كانت فارغة. إكيريابلز هي مجرد استفسارات، وليس البيانات. أجاب على 5 يونيو 14 في 16:23 تعليق أن إنوميراتابلز دائما في الذاكرة ليست صحيحة بالضرورة. واجهة إكوريابل تنفذ واجهة إينوميرابل. وبسبب هذا، يمكنك تمرير إكوريابل الخام الذي يمثل الاستعلام لينق إلى سكل الحق في وجهة نظر التي تتوقع إينوميرابل قد تفاجأ أن تجد أن سياق البيانات الخاصة بك قد انتهت أو أن ينتهي بك الأمر في القضايا مع مارس ( مجموعات نتائج نشطة متعددة). نداش الكسندر بريتشارد 22 يناير 20 في 20:13 لذلك، في الواقع، يمكنك can39t حقا استدعاء أي عضو إينوميرابل دون وجود الكائن في الذاكرة. وسوف تحصل في هناك إذا كنت تفعل، على أي حال، إذا it39s لا فارغة. إكيريابلز هي مجرد استفسارات، وليس البيانات. ولكنني أرى حقا وجهة نظرك. I39m ستعمل إضافة تعليق على هذا. نداش أرمان مشيتاريان فبراير 4 15 في 10:58 أليكساندربريتشارد لا شيء منهم هي الأشياء في الذاكرة منذ أنهم 39re لا أنواع حقيقية في حد ذاتها، علامات 3939 من نوع - إذا كنت تريد أن تذهب عميقا. ولكن من المنطقي (وهذا 39s لماذا حتى مسن وضعه بهذه الطريقة) للتفكير في إينوميرابلز كما في الذاكرة مجموعات في حين إكيريابلز كأشجار التعبير. النقطة هي أن واجهة إكيريابل ترث واجهة إينوميرابل بحيث إذا كان يمثل استعلام، يمكن تعداد نتائج هذا الاستعلام. ويؤدي التعداد إلى تنفيذ شجرة التعبير المرتبطة بكائن قابل للتكرار. ندش أرمان مشيتاريان فبراير 4 15 في 11:02 لقد واجهت مؤخرا قضية مع إينومرابل ضد. الخوارزمية المستخدمة لأول مرة إجراء استعلام إكيريابل للحصول على مجموعة من النتائج. ثم تم تمرير هذه إلى حلقة فوريش، مع العناصر مثبتة كفئة إف. ثم تم استخدام هذه الفئة إف في جملة من استعلام لينق إلى الكيان، مما يؤدي إلى أن تكون النتيجة إينوميرابل. إم جديدة إلى حد ما ل إف و لينق للكيانات، لذلك استغرق بعض الوقت لمعرفة ما كان عنق الزجاجة. باستخدام مينيبروفيلينغ، وجدت الاستعلام ثم قم بتحويل كافة العمليات الفردية إلى استعلام لينق واحد ل كيتي الاستعلام. استغرق إينوميرابل 15 ثانية و استغرق إكيريابل 0.5 ثانية لتنفيذ. كانت هناك ثلاثة الجداول المعنية، وبعد قراءة هذا، وأعتقد أن الاستعلام إنوميرابل كان في الواقع تشكيل ثلاثة عبر الجدول المنتج وتصفية النتائج. حاول استخدام إكيريابلز كقاعدة أساسية وإبراز عملك لجعل التغييرات قابلة للقياس. أجاب 12 12 في 20:39 السبب في أن يتم تحويل التعبيرات إكيريابل إلى سكل الأصلي في إف ويتم تنفيذها الحق في دب بينما القوائم إنوميرابل الكائنات في الذاكرة. أنها تحصل على جلب من دب في مرحلة ما عند استدعاء وظائف تجميع مثل عدد، مجموع، أو أي ل. وتعمل في الذاكرة بعد ذلك. كما تتعثر s متيقظة في الذاكرة مرة واحدة you39ve دعا واحدة من تلك واجهات برمجة التطبيقات ولكن إذا لم يكن كذلك، يمكنك تمرير التعبير عن كومة من الطبقات واللعب حولها مع المرشحات حتى استدعاء أبي. المصممة تصميما جيدا دال كمستودع تصميم جيد سيحل هذا النوع من المشاكل) نداش أرمان مشيتاريان يونيو 5 14 في 15:29 أود أن أوضح بعض الأشياء بسبب الردود المتضاربة على ما يبدو (في الغالب المحيطة إينوميرابل). (1) إكيريابل يمتد واجهة إينوميرابل. (يمكنك إرسال إكيريابل إلى شيء الذي يتوقع إينوميرابل دون خطأ.) (2) كلا إكيريابل و إنوميرابل لينق محاولة التحميل كسول عند تكرار على مجموعة نتيجة. (لاحظ أن التنفيذ يمكن أن ينظر إليه في أساليب تمديد واجهة لكل نوع.) وبعبارة أخرى، إنوميرابلز ليست حصرا في الذاكرة. لا يتم تنفيذ إكيريابلز دائما على قاعدة البيانات. إينوميرابل يجب تحميل الأشياء في الذاكرة (مرة واحدة استرجاعها، ربما بالكسل) لأنه لا يوجد لديه مزود البيانات المجردة. تعتمد إكيريابلز على مزود مجرد (مثل لينق إلى سكل)، على الرغم من أن هذا يمكن أن يكون أيضا موفر الذاكرة. (أ) استرداد قائمة السجلات على أنها متوقعة من سياق إف. (لا توجد سجلات في الذاكرة.) (ب) تمرير إكيريابل إلى عرض الذي هو إنوميرابل النموذج. (ساري المفعول قابل للتوسيع إينوميرابل.) (ج) تتدخل على والوصول إلى سجلات مجموعات البيانات والكيانات والخصائص الطفل من وجهة نظر. (قد يسبب استثناءات) (1) محاولات إنوميرابل التحميل كسول وسياق البيانات الخاصة بك منتهية الصلاحية. تم طرح الاستثناء لأن موفر الخدمة لم يعد متوفرا. (2) يتم تمكين وكلاء كيانات إطار الكيان (الافتراضي)، وتحاول الوصول إلى كائن (ظاهري) ذي صلة مع سياق بيانات منتهية الصلاحية. نفس (1). (3) مجموعات نتائج نشطة متعددة (مارس). إذا كنت تتكرر على إينوميرابل في فوريش (سجل فار في ريسولتسست) كتلة ومحاولة في وقت واحد للوصول إلى record. childEntity. childProperty. قد ينتهي بك الأمر مع مارس بسبب التحميل كسول من كل من مجموعة البيانات والكيانات العلائقية. سيؤدي هذا إلى استثناء إذا لم يتم تمكينه في سلسلة الاتصال الخاصة بك. لقد وجدت أن تمكين مارس في سلسلة اتصال يعمل بشكل لا يمكن الاعتماد عليه. أقترح عليك تجنب مارس إلا إذا كان مفهوما جيدا والمطلوبة صراحة. تنفيذ الاستعلام وتخزين النتائج عن طريق استدعاء النتائج ريليستليست. سيليكت () يبدو أن هذه هي الطريقة الأكثر مباشرة لضمان الكيانات الخاصة بك هي في الذاكرة. في الحالات التي تقوم فيها بالوصول إلى كيانات ذات صلة، قد لا تزال بحاجة إلى سياق بيانات. إما ذلك، أو يمكنك تعطيل وكلاء الكيانات و تضمين الكيانات ذات الصلة صراحة من دبسيت الخاص بك. والفرق الرئيسي بين إينوميرابل و إكيريابل هو حول حيث يتم تنفيذ منطق مرشح. واحد ينفذ على جانب العميل (في الذاكرة) والآخر ينفذ على قاعدة البيانات. على سبيل المثال، يمكننا أن ننظر في مثال حيث لدينا 10،000 سجلات لمستخدم في قاعدة البيانات الخاصة بنا، ويسمح فقط 900 التي هي المستخدمين النشطين، لذلك في هذه الحالة إذا كنا نستخدم إينوميرابل ثم أولا بتحميل كافة السجلات 10000 في الذاكرة ثم ينطبق مرشح إيساكتيف على ذلك الذي يعود في نهاية المطاف 900 مستخدم نشط. بينما من ناحية أخرى على نفس الحالة إذا كنا نستخدم إكويريابل فإنه سيتم تطبيق مباشرة مرشح إيساكتيف على قاعدة البيانات التي مباشرة من هناك سيعود 900 مستخدم نشط. أجاب مايو 9 16 في 12:03 لذلك وهو أمر جيد للاستخدام. في هذا السيناريو. نداش الجدد 23 يناير في 9:08 يمكننا استخدام على حد سواء لنفس الطريقة، وأنها تختلف فقط في الأداء. إكيريابل ينفذ فقط ضد قاعدة البيانات بطريقة فعالة. وهذا يعني أنه يخلق الاستعلام حدد كامل ويحصل فقط على السجلات ذات الصلة. على سبيل المثال، نريد أن نأخذ أفضل 10 عملاء يبدأ اسمهم مع نيمال. في هذه الحالة سيتم إنشاء الاستعلام المحدد كما حدد أعلى 10 من العملاء حيث اسم مثل نيمال. ولكن إذا استخدمنا إينوميرابل، فإن الاستعلام سيكون مثل اختيار من العملاء حيث سيتم تصفية اسم مثل نيمال والعشرة الأوائل على مستوى الترميز C (يحصل على كافة سجلات العملاء من قاعدة البيانات ويمر بها إلى C). أجاب مار 25 16 في 7:02 أثناء استخدام لينق للكيانات، من المهم أن نفهم متى لاستخدام إينوميرابل و إكيريابل. إذا كنا نستخدم إينوميرابل، سيتم تنفيذ الاستعلام على الفور. إذا كنا نستخدم إكيريابل، سيتم تأجيل تنفيذ الاستعلام حتى يطلب التطبيق التعداد. الآن دعونا نرى ما ينبغي النظر في حين تقرر ما إذا كان استخدام إكيريابل أو إينوميرابل. استخدام إكيريابل يتيح لك فرصة لإنشاء استعلام لينق معقدة باستخدام عبارات متعددة دون تنفيذ الاستعلام على مستوى قاعدة البيانات. يتم تنفيذ الاستعلام فقط عند استعلام الاستعلام لينق النهائي. أجاب 10 يوليو 15 في 16:34 كلا إكيريابل و إينوميرابل إرجاء التنفيذ. الفرق هو ما إذا كان يتم العمل في دب أو في الذاكرة، وليس عند القيام به. ناداش سيرفي 10 يوليو 15 في 16:45 الجواب الخاص بك 2017 كومة الصرف، إنكبيرسونالي، وأعتقد أن القدرة على الاعتراف ومواجهة أخطائك هو أثر جانبي قيمة من اكتساب الخبرة والثقة كمطور. I can8217t تساعدك على الخروج من 8220Imposter متلازمة Jail8221 في حد ذاته، ولكن أستطيع أن أقول للمطورين الأصغر سنا أن you8217ll تكون قادرة على أن تكون أكثر تفاؤلا عن الأخطاء التي تقوم بها في اتخاذ القرارات التقنية الخاصة بك بمجرد الحصول على التفكير بأنك بحاجة إلى إثبات يستحق الجميع من حولك في جميع الأوقات. هذا المنصب قد يكون شيئا ولكن السرة يحدق، ولكن I8217d الرهان there8217s شيء هنا التي تتعلق معظم المطورين عاجلا أو آجلا. I8217ve كان بعض من هذه الأخطاء يفرك في وجهي هذا الأسبوع لذلك كان هذا في ذهني. قبل بضع سنوات كنت قد قلت أن أكبر خطأ بلدي كان الفشل في توفير وثائق كافية ومثال الأعراف. اليوم I8217ll وضع بسعادة مارتن. StructureMap. أو ستوريتيلر الوثائق ضد تقريبا أي مشروع أوس، لذلك I8217m الذهاب لتمرير على كونه مذنب عن تلك الخطايا الماضية. دون 8217t يطير سولو على أشياء كبيرة وأعتقد أنه من الممكن تماما 8217s للعمل من قبل نفسك على المكتبات الصغيرة، مكتفية ذاتيا. إذا كنت 8217re تحاول أن تفعل شيئا كبيرا على الرغم من you8217re سوف تحتاج إلى مساعدة من أشخاص آخرين. من الناحية المثالية، you8217ll تحتاج الترميز الفعلي والاختبار مساعدة، ولكن على الأقل you8217ll تحتاج ردود الفعل والأفكار ميزة من أشخاص آخرين. إذا كان لديك أي رغبة في رؤية مشروعك جذب استخدام كبير، you8217ll تريد بالتأكيد الناس الآخرين الذين يستثمرون أيضا في رؤية المشروع الخاص بك تنجح. أنا can8217t مساعدتك كثيرا هنا فيما يتعلق كيفية تحقيق كامل 8220build حيوية أوس المجتمع 8221 شيء. بخلاف مارتن، I8217ve لم تكن ناجحة جدا في مساعدة تنمو مجتمع حول أي من الأدوات I8217ve بنيت. فوبومفك لديها مجتمع كبير في البداية، ولكن أنا سمة أكثر من ذلك بكثير لتشاد مايرز وجوش أرنولد من أي شيء فعلته في ذلك الوقت. أعتقد أن الوقت هو الخطي في كل مرة واحدة جعل الإفراج ستروتورماب أشعر 8220that8217s ذلك، I8217m فعلت أخيرا مع هذا الشيء، وأنا يمكن أن تنتقل إلى أشياء أخرى الآن .8221 اعتقدت أن الإصدار 3.0 كان على وشك حل دائم أسوأ من StructureMap8217s الهيكلية والأداء العيوب. ثم جاء أسب كور، و كوريكلر، والرغبة في تسريع وقتنا بوتسترابينغ التطبيق، وذلك جاء جاء ستروتورماب 4.0 8212 وهذه المرة أنا حقا الانتهاء، شكرا لك. إلا أنني كان 8217t. وجد المستخدمون أخطاء جديدة من حالات الاستخدام I8217d لم ينظر فيها (و willn8217t استخدام على أي حال، ولكن أنا دغريس). كوري كايلور وأنا انتهى الأمر ببعض التحسينات الأداء ستروتورماب في أواخر العام الماضي أن انسداد بعض القضايا مع ستروتورماب في تركيبة مع بعض الأدوات التي نستخدمها. فقط هذا الاثنين قضيت 3-4 ساعات معالجة البق المعلقة وسحب طلبات لدفع الإصدار الجديد. وجهة نظري هنا هو اعتماد عقلية أن نشاطك على مشروع أوس هو دوري، وليس الخطية. ولا تكتمل أبدا نظم البرمجيات أو أطرها أو مكتباتها، ولا يتم التخلي عنها إلا. وكان هذا بلدي أكبر خطأ واحد، و it8217s حقا قضية من منظور. كن واقعيا حول دعم المستخدمين I8217ve كان القضايا من وقت لآخر على ستروتورماب عندما أحصل على الجرح شعور مثل كنت باكلوغيد جدا مع أسئلة المستخدم والمشاكل مع مزيج من الشعور بالذنب والإحباط. أعتقد أن الجواب الحقيقي الوحيد هو أن يكون واقعيا فقط حول مدى السرعة التي يمكن أن تحصل على جميع أنحاء لمعالجة قضايا المستخدم وقطع نفسك قليلا من الركود. عائلتك، ومكان عملك، وعليك أن تكون أولوية أعلى من شخص على شبكة الانترنت. بناء الميزات في وقت مبكر جدا في الأيام الأولى للتنمية رشيقة تحدثنا قليلا عن 8220pull8221 مقابل 8220push8221 نهج لنطاق المشروع. في نمط 8220push8221، حاولت التخطيط في وقت مبكر ما الميزات والبنية التحتية you8217re سوف تحتاج، وبناء ذلك في وقت مبكر. في نمط 8220pull8221، يمكنك تأخير إدخال بنية تحتية جديدة أو ميزات حتى هناك 8217s حاجة واضحة لذلك. كانت تجربتي الثابتة على مدى العقد الماضي أن الميزات التي بنيت في رد فعل على حاجة محددة على مشروع مستمر في العمل كانت أكثر نجاحا بكثير من الأفكار أنا التشويش في بلدي مشروع أوس لأنه بدا باردا في ذلك الوقت. دوغفودينغ حاول عدم وضع أي شيء هناك للاستهلاك من قبل الآخرين إذا كنت haven8217t استخدامها بنفسك في مواقف واقعية. أنا ربما قفزت بندقية على الإصدار ستوريتيلر 4.0 و I8217ll تحتاج إلى دفع الإصدار الجديد الأسبوع المقبل لمخاوف قابليتها للاستخدام والبق زوجين. كل من هذا الإجهاد كان يمكن تجنبها إذا I8217d مجرد استخدام alpha8217s في أكثر من المشاريع الخاصة بي قبل قطع نوجيت. من ناحية أخرى، وأحيانا ما تحتاجه أكثر هو ردود الفعل من الناس الآخرين. وأتساءل عما إذا كنت قد ارتكبت خطأ إضافة وظيفة مصادر الحدث في مارتن. المشروع الذي كان في الاعتبار أنه كان قد استخدم هذا في العمل تم تأجيله إلى أجل غير مسمى و I8217m لا حقا دوجفودينغ على الإطلاق نفسي. لحسن الحظ، كان العديد من الناس الآخرين استخدامه في سيناريوهات واقعية و I8217m تعتمد اعتمادا كليا تقريبا عليها لإيجاد مشاكل أو اقتراح التحسينات أو تغييرات أبي. وأعتقد أن وظيفة سوف تحسن كثيرا أسرع إذا كنت دوغفودينغ واحد، ولكن هذا 8217s لا يحدث في أي وقت قريب. مراجعة غير كافية من طلبات السحب أحاول أن أخطئ إلى جانب أخذ طلبات السحب عاجلا وليس آجلا، وغالبا ما يسبب المتاعب أسفل الطريق. في طريقة، it8217s من الصعب معالجة رمز من شخص آخر لميزات جديدة لأنك 8217re لا تستثمر في رؤية طريقك من خلال الآثار المحتملة غوتشاس. أرى طلب سحب يأتي مع اختبارات كافية وأميل إلى أن أعتبر فيها. كانت هناك عدة مرات عندما كنت أفضل من التوقف والتفكير في كيفية تناسبها مع بقية المشروع. أنا don8217t أعرف ما هي الإجابة بالضبط هنا. صرامة جدا من متطلبات طلبات سحب وكنت win8217t الحصول على أي. الإشراف قليلا جدا يؤدي لك دعم شخص آخر رمز 8217s. أوفيريش و غطرسة أنا أكره أن أقول لك mustn8217t مطاردة أحلام أوس الخاص بك، ولكن أعتقد أن عليك أن تكون حريصا على عدم الإفراط أو اتخاذ مهمة مستحيلة. أخذ بلدي فلاموت مذهلة مع مشروع فوبومفك كمثال، وأعتقد أنني شخصيا جعلت هذه الأخطاء: كونها وسيلة جدا غرانديوس. وكان البديل تماما تطوير شبكة الإنترنت والإطار حافلة الخدمة مع مفاهيمها الخاصة من نمطية بعيدا خارج التيار الرئيسي فقط لن يذهب. أعتقد أنك أكثر عرضة للنجاح من خلال كونك جزءا من نظام بيئي قائم بدلا من محاولة إنشاء نظام بيئي جديد كليا. أعتقد I8217m قائلا هو أن هناك مجرد aren8217t الذهاب إلى أن يكون DHH8217s كثيرة جدا أو جون Resig8217s. بناء البنية التحتية التي كان 8217t تتعلق مباشرة إلى جوهر المشروع الخاص بك. وشملت فوبومفك في النهاية محرك القوالب الخاصة بالمشروع الخاص بها، والبرنامج الوسيطة للملفات الثابتة، ومزود SAML2، ومختلف القدرات الأخرى التي كان بإمكاني سحبها من الرف بدلا من بناء نفسي. كل هذه الأشياء الإضافية تمثل تكلفة فرصة كبيرة لنفسي. مجرد شقة من بناء الكثير من الاشياء بدلا من التركيز على تحسين جوهر المشروع الخاص بك في حين أن هذا هو مظاهرة العمل على مربع بلدي، ما I8217m تظهر هنا هو نهج مفاهيمي في وقت مبكر جدا لاستعراض من قبل الناس الآخرين في متجري. I8217d أحب أن يكون أي ردود فعل على هذا الشيء. قضيت قليلا من الوقت في مكتبنا سولت لايك سيتي الأسبوع الماضي التحدث مع موظفينا كا حول أتمتة الاختبار بشكل عام وحيث سلينيوم يفعل أو doesn8217t تناسب في منطقتنا (المطلوب) النهج. المطورين في متجري استخدام السيلينيوم قليلا جدا اليوم داخل جناح قبول القصة لدينا مع نتائج مختلطة، ولكن الآن لدينا كا الناس يريدون لأتمتة بعض من مجموعة الاختبار اليدوي والركل الإطارات على السيلينيوم. وكمتابعة لتلك المناقشات، يظهر هذا المنصب المفهوم المبكر جدا لكيفية استخدام وظائف السيلينيوم ضمن مواصفات ستوريتيلر لتعليقاتهم وملاحظاتهم. كل من التعليمات البرمجية في storyteller8217s 4.1 فرع. عرض مواصفات Let8217s بدء الخام جدا. Let8217s يقول أن لديك صفحة ويب تحتوي على علامة مع نوع من نص رسالة المستخدم التي 8217s مخفية في البداية. وعلاوة على ذلك، Let8217s يقول أن كنت 8217ve حصلت على زرين على الشاشة مع النص 8220Show8221 و 8220Hide.8221 مواصفات القصة لهذا السلوك قد تبدو كما يلي: و هتمل النتائج سوف تبدو كما يلي: 3 وقت التشغيل الثاني هو في الغالب في إنشاء وإطلاق مثيل متصفح كروم. المزيد عن هذا لاحقا. ولتنفيذ هذه المواصفة نحتاج إلى أمرين، هما فصول تركيبات تقوم بتنفيذ لغتنا المرغوبة وبيانات المواصفات الفعلية في ملف تهجير يظهر في القسم التالي. في هذا المثال، سيكون هناك مكتبة جديدة 8220Storyteller. Selenium8221 التي توفر الأساس لدمج السيلينيوم في مواصفات القصة مع 8220ScreenFixture 8221 الطبقة الأساسية المشتركة للفيكستور 8217s التي تستهدف السيلينيوم. بعد ذلك، الطبقة سامبلفيكستور المستخدمة في مواصفات أعلاه يبدو مثل هذا: إذا كنت تقوم بتحرير المواصفات في storyteller8217s محرر مواصفات. you8217ll لديك مربع المنسدلة إدراج العناصر بالاسم أي مكان حيث تحتاج إلى تحديد عنصر مثل ذلك: وأخيرا، فإن حزمة Storyteller. Selenium المقترحة يضيف معلومات إلى تسجيل الأداء لمدة طويلة صفحة ويب يأخذ لتحميل. هذا هو الوقت وفقا ل ويبدريفر و willn8217t استخدامها لتحسين الأداء التفصيلي، لكنه لا يزال 8217s عددا مفيدا لفهم مشاكل الأداء أثناء إعدام تنفيذ ستوريتيلر مواصفات. راجع سطر 8220Navigationimple. htm8221 أدناه: ما هي المواصفات الفعلية التي تبدو وكأنها إذا قمت بتأليف المواصفة أعلاه في واجهة مستخدم ستوريتيلر، فإنك تحصل على ملف التضمين هذا: 8217d: ومع ذلك، إذا كنت تكتب المواصفات يدويا في ملف تخفيض الأسعار مباشرة، يمكن تبسيط ذلك: نحن W8217re تحاول بجد مع ستوريتيلر 4 لجعل مواصفات أسهل للكتابة لغير المطورين وما تراه أعلاه هو نتاج هذا الجهد. لماذا القصة السيلينيوم بدلا من مجرد السيلينيوم لماذا تريد استخدام القصة والسيلينيوم معا بدلا من مجرد السيلينيوم في حد ذاته أسباب زوجين: هناك 8217s الكثير من الذهاب في اختبارات مؤتمتة فعالة إلى جانب قيادة متصفحات الويب (إعداد بيانات النظام، والتحقق من بيانات النظام ، بدء تشغيل النظام تحت الاختبار). القصة يوفر الكثير من الوظائف من السيلينيوم في حد ذاته. It8217s قيمة جدا للتعبير عن الاختبارات الآلية في لغة مستوى أعلى مع شيء مثل ستوريتيلر أو الخيار بدلا من الذهاب إلى أسفل إلى عناصر الشاشة وغيرها من تفاصيل التنفيذ. وأنا أقول هذا جزئيا لجعل المواصفات أكثر إنسانية للقراءة، ولكن أيضا لفصل التعبير عن الاختبار من تفاصيل التنفيذ الأساسية. كنت تريد أن تفعل ذلك بحيث الاختبارات الخاصة بك يمكن أن تستوعب بسهولة التغييرات الهيكلية لصفحات الويب. إذا كنت 8217ve لم تعمل على نطاق واسع اختبار الآلي ضد متصفح الويب، وكنت حقا بحاجة إلى أن ندرك أن هذه الأنواع من الاختبارات يمكن أن تكون هشة جدا في مواجهة التغييرات واجهة المستخدم. يوفر القصي الكثير من الأجهزة الإضافية والأداء تسجيل التي يمكن أن تكون مفيدة جدا لتصحيح الأخطاء أو مشاكل الأداء أنا أكره أن رمي هذا واحد هناك، ولكن Storyteller8217s شكلي القدرة على إعادة المحاولة في التكامل المستمر هو مفيد جدا لأجنحة اختبار مع خرب من السلوك غير المتزامن مثل كنت كثيرا ما واجهت مع تطبيقات الويب الحديثة لأن شخص ما سوف يسأل، أو متحمس F سوف رمي حتما هذا هناك، نعم، هناك 8217s الستارة كذلك أن يلتف دسل لطيفة حول السيلينيوم ويوفر بعض الاستقرار. I8217m لا التقليل المظلة في أدنى، ولكن كل ما قلت عن استخدام السيلينيوم الخام ينطبق بالتساوي على استخدام الستارة في حد ذاته. لتكون أكثر قليلا بوكي العين حول هذا الموضوع، واحدة من قصص النجاح الأولى من ستوريتيلر 3 كان في استبدال جناح اختبار غير مستقرة بشكل سيء التي استخدمت الستارة ساذجة. رواية القصص هو مشروع طويل المدى لتأليف مقروءه، قابلة للتنفيذ للمواصفات للمشاريع. ويهدف الإصدار الجديد 4.0 لجعل ستوريتيلر أسهل للاستخدام والاستهلاك للأشخاص غير التقنيين وتحسين قدرة المطور 8217s لاستكشاف فشل المواصفات. بعد حوالي 5 أشهر من الجهد، وكنت في النهاية قادرا على خفض 4.0 نوجيتس لرواية القصص هذا الصباح وأحدث التحديثات الوثائق. إذا كنت 8217re جديدة تماما ل ستوريتيلر، تحقق من صفحة البدء لدينا أو هذا البث الشبكي. إذا كنت 8217re القادمة من ستوريتيلر 3.0، ونعرف فقط أنك سوف تحتاج إلى أولا تحويل المواصفات الخاصة بك إلى تنسيق 4.0 الجديد. لم يكن لدى أبي ستوريتيلر تركيبات أي كسر، ولكن الخطوات بوتسترابينغ مختلفة قليلا لاستيعاب دوتنيت كلي. يمكنك الاطلاع على قائمة التغييرات بالكامل هنا. أو أبرز كبير من هذا الإصدار هي: كوريكلر دعم ستوريتيلر 4.0 يمكن استخدامها على أي من المشاريع 4.6 أو المشاريع التي تستهدف كوركلر. واعتبارا من الآن، ستوريتيلر هو الآن أداة عبر منصة. يمكنك قراءة المزيد عن تجربتي ترحيل رواية القصص إلى كوركلر هنا. يضم دوتنيت كلي. أنا أحب الجديد دوتنيت كلي وأتمنى we8217d كان عليه قبل سنوات. هناك 8220dotnet جديدة القصة 8221 كلي حزمة التمدد الذي يأخذ مكان أداة وحدة التحكم ST. exe القديمة في 3.0 التي ينبغي أن يكون أسهل لإعداد للمستخدمين الجدد. تخفيض السعر في كل مكان ستوريتيلر 4.0 غيرت شكل مواصفات إلى تخفيض السعر بالإضافة إلى شكل. وأضاف قدرة جديدة لتصميم وتوليد فيكستور 8217s مع تخفيض السعر. ويمكنك استخدام بسعادة النص تخفيض النص كما النثر ضمن المواصفات لتحسين قدرتك على التواصل النوايا في مواصفات القصة. وضع خطوة. اختبارات التكامل يمكن أن تكون صعبة جدا لتصحيح عندما تفشل. لتخفيف الحمل، ستوريتيلر 4.0 يضيف وضع ستيبثرو الجديد الذي يسمح لك المشي يدويا من خلال جميع الخطوات للمواصفات ستوريتلر حتى تتمكن من فحص الحالة الحالية للنظام تحت الاختبار كمساعدة في استكشاف الأخطاء وإصلاحها. Asynchronous Grammars . It8217s increasingly an async-first kind of world, so Storyteller follows suit to make it easier for you to test asynchronous code . Performance Assertions . Storyteller already tracks some performance data about your system as specifications run, so why not extend that to applying assertions about expected performance that can fail specifications on your continuous integration builds Other Things Coming Soon(ish) A helper library for using Storyteller with ASP Core applications with some help from Alba. I8217m hoping to recreate some of the type of diagnostics integration we have today with Storyteller and our FubuMVC applications at work for our newer ASP Core projects. A separate package of Selenium helpers for Storyteller An extension specifically for testing relational database code A 4.1 release with the features I didn8217t get around to in 4.0) How is Storyteller Different than Gherkin Tools First off, can we just pretend for a minute that GherkinCucumber tools like SpecFlow may not be the absolute last word for automating human readable, executable specifications By this point, I think most folks associate any kind of acceptance test driven development or truly business facing Behavioral Driven Development with the Gherkin approach 8212 and it8217s been undeniably successful. Storyteller on the other hand, was much more influenced by Fitnesse and could accurately be described as a much improved evolution of the old FIT model . SpecFlow is the obvious comparison for Storyteller and by far the most commonly used tool in the space. The bottom line for me with Storyteller vs. SpecFlow is that I think that Storyteller is far more robust technically in how you can approach the automated testing aspect of the workflow. SpecFlow might do the businesstesting to development workflow a little better (but I8217d dispute that one too with the release of Storyteller 4.0), but Storyteller has much, much more functionality for instrumenting, troubleshooting, and enforcing performance requirements of your specifications. I strongly believe that Storyteller allows you to tackle much more complex automated testing scenarios than other options. Here is a more detailed list about how Storyteller differs from SpecFlow: Storyteller is FOSS. So on one hand, you don8217t have to purchase any kind of license to use it, but you8217ll be dependent upon the Storyteller community for support. Instead of parsing human written text and trying to correlate that to the right calls in the code, Storyteller specifications are mostly captured as the input and expected output. Storyteller specifications are then 8220projected8221 into human readable HTML displays. Storyteller is much more table centric than Gherkin with quite a bit of functionality for set-based assertions and test data input. Storyteller has a much more formal mechanism for governing the lifecycle of your system under test with the specification harness rather than depending on an application being available through other means. I believe that this makes Storyteller much more effective at development time as you cycle through code changes when you work through specifications. Storyteller does not enforce the 8220GivenWhenThen8221 verbiage in your specifications and you have much more freedom to construct the specification language to your preferences. Storyteller has a user interface for editing specifications and executing specifications interactively (all React. js based now). The 4.0 version makes it much easier to edit the specification files directly, but the tool is still helpful for execution and troubleshooting. We do not yet have direct Visual Studio integration like SpecFlow (and I8217m somewhat happy to let them have that one)), but we will develop a dotnet test adapter for Storyteller when the dust settles on the VS2017csproj churn. Storyteller has a lot of functionality for instrumenting your specifications that8217s been indispensable for troubleshooting specification failures and even performance problems. The built in performance tracking has consistently been one of our most popular features since it was introduced in 3.0. When I was at Codemash this year, Matthew Groves was kind enough to let me do a podcast with him on Marten for the Cross Cutting Concerns podcast. Check it out . I8217m flying out to our main office next week and one of the big things on my agenda is talking over our practices around databases in our software projects. This blog post is just me getting my thoughts and talking points together beforehand. There are two general themes here, how I8217d do things in a perfect world and how to make things better within the constraints of the organization and software architecture that have now. I8217ve been a big proponent of Agile development processes and practices going back to the early days of Extreme Programming (before Scrum came along and ruined everything about the way that Scrappy ruined Scooby Doo cartoons for me as a child). If I8217m working in an Agile way, I want: Strong project and testing automation as feedback cycles that run against all changes to the system Some kind of easy traceability from a built or deployed system to exactly the version of the code and its dependencies. preferably automated through your source control processes Technologies, tools, and frameworks that provide high reversibility to ease the cost of doing evolutionary software design. From the get go, relational databases have been one of the biggest challenges in the usage of Agile software practices. They8217re laborious to use in automated testing, often expensive in time or money to install or deploy, the change management is a bit harder because you can8217t just replace the existing database objects the way we can with other code, and I absolutely think it8217s reduces reversibility in your system architecture compared to other options. That being said, there are some practices and processes I think you should adopt so that your Agile development process doesn8217t crash and burn when a relational database is involved. Keep Business Logic out of the Database, Period. I8217m strongly against having any business logic tightly coupled to the underlying database. but not everyone feels the same way. For one reason, stored procedure languages (tSQL, PLSQL, etc.) are very limited in their constructs and tooling compared to the languages we use in our application code (basically anything else). Mostly though, I avoid coupling business logic to the database because having to test through the database is almost inevitably more expensive both in developer effort and test run times than it would be otherwise. Some folks will suggest that you might want to change out your database later, but to be honest, the only time I8217ve ever done that in real life is when we moved from RavenDb to Marten where it had little impact on the existing structure of the code. In practice this means that I try to: Eschew usage of stored procedures. Yes, I think there are still some valid reasons to use sprocs, but I think that they are a 8220guilty until proven innocent8221 choice in almost any scenario Pull business logic away from the database persistence altogether whenever possible. I think I8217ll be going back over some of my old designing for testability blog posts from the CodebetterALT days to try to explain to our teams that 8220wrap the database in an interface and mock it8221 isn8217t always the best solution in every case for testability Favor persistence tools that invert the control between the business logic and the database over tooling like Active Record that creates a tight coupling to the database. What this means is that instead of having business logic code directly reading and writing to the database, something else (Dapper if we can, EF if we absolutely have to) is responsible for loading and persisting application state back and forth between the domain in code and the underlying database. The point is to be able to completely test your business logic in complete isolation from the database. I would make exceptions for use cases where using the database engine to do set based logic in a stored procedure is a more efficient way to solve the problem, but I haven8217t been involved in systems like that for a long time. Database per DeveloperTesterEnvironment My very strong preference and recommendation is to have each developer, tester, and automated testing environment using a completely separate database. The key reason is to isolate each thread of team activity to avoid simultaneous operations or database changes from interfering with each other. Sharing the database makes automated testing much less effective because you often get false negatives or false positives from database activity going on somewhere else at the same time 8212 and yes, this really does happen and I8217ve got the scars to prove it. Additionally, it8217s really important for automated testing to be able to tightly control the inputs to a test. While there are some techniques you can use to do this in a shared database (multi-tenancy usage, randomized data), it8217s far easier mechanically to just have an isolated database that you can easily control. Lastly, I really like being able to look through the state of the database after a failed test. That8217s certainly possible with a shared database, but it8217s much easier in my opinion to look through an isolated database where it8217s much more obvious how your code and tests changed the database state. I should say that I8217m concerned here with logical separation between different threads of activity. If you do that with truly separate databases or separate schemas in the same database, it serves the same goal. 8220The8221 Database vs. Application Persistence There are two basic development paradigms to how we think about databases as part of a software system: The database is the system and any other code is just a conduit to get data back and forth from the database and its consumers The database is merely the state persistence subsystem of the application I strongly prefer and recommend the 2nd way of looking at that, and act accordingly. That8217s a admittedly a major shift in thinking from traditional software development or database centric teams. In practice, this generally means that I very strongly favor the concept of an application database that is only accessed by one application and can be considered to be just part of the application. In this case, I would opt to have all of the database DDL scripts and migrations in the source control repository for the application. This has a lot of benefits for development teams: It makes it dirt simple to correlate the database schema changes to the rest of the application code because they8217re all versioned together Automated testing is easier within continuous integration builds becomes easier because you know exactly what scripts to apply to the database before running the tests No need for elaborate cascading builds in your continuous integration setup because it8217s just all together In contrast, a shared database that8217s accessed by multiple applications is a lot more potential friction. The version tracking between the two moving parts is harder to understand and it harms your ability to do effective automated testing. Moreover, it8217s wretchedly nasty to allow lots of different applications to float on top of the same database in what I call the 8220pond scum anti-pattern8221 because it inevitably causes nasty coupling issues that will almost result in regression bugs due to it being so much harder to understand how changes in the database will ripple out to the applications sharing the database. A much, much younger version of myself walked into a meeting and asked our 8220operational data store8221 folks to add a column to a single view and got screamed at for 30 minutes straight on why that was going to be impossible and do you know how much work it8217s going to be to test everything that uses that view young man Assuming that you absolutely have to continue to use a shared database like my shop does, I8217d at least try to ameliorate that by: Make damn sure that all changes to that shared database schema are captured in source control somewhere so that you have a chance at effective change tracking Having a continuous integration build for the shared database that runs some level of regression tests and then subsequently cascades to all of the applications that touch that database being automatically updated and tested against the latest version of the shared database. I8217m expecting some screaming when I recommend that in the office next week-) At the least, have some mechanism for standing up a local copy of the up to date database schema with any necessary baseline data on demand for isolated testing Some way to know when I8217m running or testing the dependent applications exactly what version of the database schema repository I8217m currently using. Git submodules Distribute the DB via Nuget Finally do something useful with Docker, distribute the DB as a versioned Docker image, and brag about that to any developer we meet The key here is that I want automated builds constantly running as feedback mechanisms to know when and what database changes potentially break (or fix too) one of our applications. Because of some bad experiences in the past, I8217m hesitant to use cascading builds between separate repositories, but it8217s definitely warranted in this case until we can get the big central database split up. At the end of the day, I still think that the shared database architecture is a huge anti-pattern that most shops should try to avoid and I8217d certainly like to see us start moving away from that model more and more. Document Databases over Relational Databases I8217ve definitely put my money where my mouth is on this (RavenDb early on, and now Marten ). In my mind, evolutionary or incremental software design is much easier with document databases for a couple reasons: Far fewer changes in the application code result in database schema changes It8217s much less work to keep the application and database in sync because the storage just reflects the application model Less work in the application code to transform the database storage to structures that are more appropriate for the business logic. أي. relational databases really aren8217t great when your domain model is logically hierarchical rather than flat It8217s a lot less work to tear down and set up known test input states in document databases. With a relational database you frequently end up having to deal with extraneous data you don8217t really care about just to satisfy relational integrity concerns. Likewise, tearing down relational database state takes more care and thought than it does with a document database. I would still opt to use a relational database for reporting or if there8217s a lot of set based logic in your application. For simpler CRUD applications, I think you8217re fine with just about any model and I don8217t object to relational databases in those cases either. It sounds trivial, but it does help tremendously if your relational database tables are configured to use cascading deletes when you8217re trying to set a database into a known state for tests. Team Organization My strong preference is to have a completely self-contained team that has the ability and authority to make any and all changes to their application database, and that8217s most definitely been valid in my experience. Have the database managed and owned separately from the development team is a frequent source of friction and definitely a major hit to your reversibility that forces you to do more potentially wrong, upfront design work. It8217s much worse when that separate team does not share your priorities or simply works on a very different release schedule. I think it8217s far better for a team to own their database 8212 or at the very worst, have someone who is allowed to touch the database in the team room and team standup8217s. If I had full control over an organization, I would not have a separate database team. Keeping developers and database folks on separate team makes your team have to spend more time on inter-team coordination, takes away from the team8217s flexibility in deciding what they can deliver, and almost inevitably causes a bottleneck constraint for projects. Even worse in my mind is when neither the developers nor the database team really understand how their work impacts the other team. Even if we say that we have a matrix organization. I want the project teams to have primacy over functional teams. To go farther, I8217d opt to make functional teams (developers, testers, DBA8217s) be virtual teams solely for the purpose of skill acquisition, knowledge sharing, and career growth. My early work experience was being an engineer within large petrochemical project teams, and the project team dominant matrix organization worked a helluva lot better than it did at my next job in enterprise IT that focused more on functional teams. As an architect now rather than a front line programmer, I constantly worry about not being able to feel the 8220pain8221 that my decisions and shared libraries cause developers because that pain is an important feedback mechanism to improve the usability of our shared infrastructure or application architecture. Likewise, I worry that having a separate database team creates a situation where they8217re not very aware of the impact of their decisions on developers or vice versa. One of the very important lessons I was taught as an engineer was that it was very important to understand how other engineering disciplines work and what they needed so that we could work better with them. Now though, I do work in a shop that has historically centralized the control of the database in a centralized database team. To mitigate the problems that naturally arise from this organizational model, we8217re trying to have much more bilateral conversations with that team. If we can get away with this, I8217d really like to see members of that team spend more time in the project team rooms. I8217d also love it if we could steal a page from my original engineering job (Bechtel ) and suggest some temporary rotations between the database and developer teams to better appreciate how the other half of that relationship works and what their needs are. I just uploaded Marten 1.3.0 to Nuget (but note that Nuget has had issues today with the index updating being delayed). This release is mostly bugfixes, but there8217s some new functionality, and significant improvements to performance on document updates and bulk inserts. You can see the entire list of changes here with some highlights below. Thanks to Phillip Haydon There8217s a slew of new documentation on our website about Postgresql for Sql Server folks . What8217s New It wasn8217t a huge release for new features, but these were added: What8217s Next The next release is going to be Marten 2.0 because we need to make a handful of breaking API changes (don8217t worry, it8217s very unlikely that most users would hit this). The big ticket item is a lot more work to reduce memory allocations throughout Marten. The other, not-in-the-slightest-bit-sexy change is to standardize and streamline Marten8217s facilities for database change tracking with the hope that this work will make it far easier to start adding new features again. Years ago when I was in college and staying at my grandparent8217s farm, my uncle rousted me up well after midnight because he could see headlights in our pasture. We went to check it out to make sure no one was trying to steal cattle (it8217s very rare, but does happen) and found one of my grandparent8217s neighbors completely stuck in a fence row and drunkenly trying to get himself out. I don8217t remember the exact 8220conversation,8221 but his vocabulary was pretty well a single four letter expletive used as noun, verb, adjective, and adverb and the encounter went pretty quickly from potentially scary to comical. Likewise, when OSS maintainers deploy the phrase 8220I take pull requests,8221 they mean a slew of very different things depending on the scenario or other party. In order of positive to negative, here are the real meanings behind that phrase if you hear it from me: I think that would be a useful idea to implement and perfectly suitable for a newcomer to the codebase. Go for it. I like that idea, but I don8217t have the bandwidth to do that right now, would you be willing to take that on I don8217t think that idea is valuable and I wouldn8217t do it if it were just me, but if you don8217t mind doing that, I8217ll take it in. You8217re being way too demanding, and I8217m losing my patience with you. Since you8217re clearly a jerk, I8217m expecting this to make you go away if you have to do anything for yourself. My shop has started to slowly transition from FubuMVC to ASP Core (w and wo MVC) in our web applications. Instead of going full blown Don Quixote and writing my own alternative web framework like I did in 2009, I8217m trying to embrace the mainstream concentrate on tactical additions where I think that makes sense. I8217ve been playing around with a small new project called Alba that seeks to make it easier to write integration tests against HTTP endpoints in ASP Core applications by adapting the 8220Scenario8221 testing mechanism from FubuMVC. I8217ve pushed up an alpha Nuget (1.0.0-alpha-28) if you8217d like to kick the tires on it. Right now it8217s very early, but we8217re going to try to use it at work for a small trial ASP Core project that just started. I8217m also curious to see if anybody is interested in possibly helping out with either coding or just flat out testing it against your own application. A Quick Example First, let8217s say we have a minimal MVC controller like this one: With that in place, I can use Alba to write a test that exercises that HTTP endpoint from end to end like this: A couple points to note here: The easiest way to tell Alba how to bootstrap your ASP application is to just pass your Startup type of your application to the SystemUnderTest. ForStartupltTgt() method shown above in the constructor function of that test fixture class. Alba is smart enough to set up the hosting content path to the base directory of your application project. To make that concrete, say your application is at 8220srcMyApp8221 and you have a testing project called 8220srcMyApp. Testing8221 and you use the standard idiom using the same name for both the directory and the assembly name. In this case, Alba is able to interrogate your MyApp. Startup type, deduce that the 8220parallel8221 folder should be 8220MyApp. Testing,8221 and automatically set the hosting content path to 8220srcMyApp8221 if that folder exists. This can of course be overridden. When the Scenario() method is called, it internally builds up a new HttpContext to represent the request, calls the lambda passed into Scenario() to configure that HttpContext object and register any declarative assertions against the expected response, and executes the request using the raw 8220RequestDelegate8221 of your ASP Core application. There is no need to be running Kestrel or any other HTTP server to use Alba 8212 but it doesn8217t hurt anything if Kestrel is running in side of your application. The Scenario() method returns a small object that exposes the HttpContext of the request and a helper object to more easily interrogate the http response body for possible further assertions. Where would this fit in Alba itself isn8217t a test runner, just a library that can be used within a testing harness like xUnit or Storyteller to drive an ASP Core application. One of the things I8217m trying to accomplish this quarter at work is to try to come up with some suggestions for how developers should decide which testing approach to take in common scenarios. Right now I8217m worried that our automated testing frequently veers off into these two non-ideal extremes: Excessive mocking in unit tests where the test does very little to ascertain whether or not the code in question would actually work in the real system End to end tests using Selenium or Project White to drive business and persistence logic by manipulating the actual web application interface. These tests tend to be much more cumbersome to write and laborious to maintain as the user interface changes (especially when the developers don8217t run the tests locally before committing code changes). Alba is meant to live in the middle ground between these two extremes and give our teams an effective way to test directly against HTTP endpoints. These Scenario() tests originally came about in FubuMVC because of how aggressive we were being in moving cross cutting concerns like validation and transaction management to fubu8217s equivalent to middleware. Unit testing an HTTP endpoint action was very simple, but you really needed to exercise the entire Russian Doll of attached middleware to adequately test any given endpoint. How is this different than Microsoft. AspNetCore. TestHost While I8217ve been very critical of Microsoft8217s lack of attention to testability in some their development tools, let me give the ASP team some credit here for their TestHost library that comes out of the box. Some of you are going to be perfectly content with TestHost, but Alba already comes with much more functionality for common set up and verifications against HTTP requests. I think Alba can provide a great deal of value to the ecosystem even with an existing solution from Microsoft. I did use a bit of code that I borrowed from an ASPNet repository that was in turn copypasted from the TestHost repository. It8217s quite possible that Alba ends up using TestHost underneath the covers. TLDR 8211 I8217m getting burned out supporting StructureMap, but it8217s still very heavily used and I8217m really hoping to recruit some new blood to eventually take the project over from me. I8217ve been mulling over whether or not I want to continue development of StructureMap. At this point, I feel like the 3.0 and 4.0 releases dealt with all the major structural and performance problems that I could think of. If you ask me what I8217d like to be do to improve one of my other OSS projects I could bend your ear for hours, but with StructureMap I8217ve got nothing in mind. The project is still very widely used (1.5M downloads from Nuget) and I don8217t mean to just drop it by any means, but I8217m wondering if anybody (hopefully plural) would like to take ownership over StructureMap and actually keep it advancing I feel like the code is pretty clean, the test coverage is solid, and there8217s even close to comprehensive documentation already published online. Why I8217ve lost enthusiasm: I8217ve worked on StructureMap since 2003 I8217m mentally exhausted trying to stay on top of the user questions and problems that come rolling in and I8217m starting to resent the obligation to try to help users unwind far out usages of the tool and dozens of disparate application frameworks. There8217s a consistent and vocal backlash against IoC containers in my Twitter feeds. To some degree, I think their experiences are just very different than my own and I don8217t recognize the problems they describe in my own usage, but it still dampens enthusiasm. I8217ve got several other projects going that I8217m frankly more passionate about right now (Marten. Storyteller. a couple others) Microsoft has a small, built in IoC container as part of ASP Core that I suspect will eventually wipe out all the myriad OSS IoC containers. I can point to plenty advantages of StructureMap over what8217s built in, but most users probably wouldn8217t really notice At this point, with every application framework or service bus, folks are putting their IoC container behind an abstraction of some kind that tends to reduce StructureMap and other tools into the least common denominator functionality, so what8217s the point of trying to do anything new if it8217s gonna be thrown away behind a lame wrapping abstraction The ASP Core compatibility has been a massive headache for me with StructureMap and I8217m dreading the kinds of support questions that I expect to roll in from users developing with ASP Core. More on this one later. EDIT 15: We8217re still hiring for Salt Lake City or Phoenix. I can probably sell a strong remote candidate in the U. S. but I can8217t get away with remote folks in Europe (sorry). We8217re (Extend Health. part of Willis Towers Watson ) doing a little bit of reorganization with our software architecture team and how it fits within the company. As part of that, we8217re looking to grow the team with open slots in our main Salt Lake City office and our new Phoenix office. We might be able to add more remote folks later (I8217m in Austin, and another member is in Las Vegas), but right now we8217re looking for someone to be local. Who we8217re looking for Let me say upfront that I have a very conflicted relationship with the term 8220software architect.8221 I8217ve been a member of the dreaded, centralized architect team where we mostly just got in the way and I8217ve had to work around plenty of architecture team8217s 8220advice.8221 This time around, I want our new architecture team to be consistently considered to be an asset to our development teams while taking care of the strategic technical goals within our enterprise architecture. More than anything, the architecture team needs to be the kind of folks that our development teams want to work with and can depend on for useful advice and help. We8217re not going to be landing huge upfront specifications and there won8217t be much UML-spewing going on. You will definitely be hands on inside the code and it8217s likely you8217ll get to work on OSS projects as part of your role (check out my GitHub profile to get an idea of the kinds of work we8217ve done over the years). You8217re going to need to have deep software development experience and been in roles of responsibility on software teams before. You8217re going to need to have strong communication skills because one of your primary duties is to help and mentor other developers. A good candidate should be thoughtful, always on the lookout for better approaches or technologies, and able to take on all new technical challenges. It8217s not absolutely required, but a healthy GitHub or other OSS profile would be a big plus. The point there is just to look for folks that actually enjoy software development. You8217ll notice that I8217m not writing up a huge bullet list of required technical acronyms. I8217m more worried about the breadth and depth of your experience than an exact fit with whatever tools we happen to be using at the moment. That being said, we8217re mostly using on the server side (but with a heavy bias toward OSS tools) and various Javascript tools in the clients with a strong preference for React. jsRedux in newer development. We do a lot of web development, quite a bit of distributed messaging work, and some desktop tools used internally. Along the way you8217ll see systems that use document databases, event sourcing, CQRS, and reactive programming. I can safely promise you that our development challenges are considerably more interesting than the average shop. آخر الملاحة
No comments:
Post a Comment