Saturday 12 August 2017

Moving average linq


IterateHelper tampaknya berlebihan. Overload yang tidak mengambil indeks akhirnya melakukan banyak pekerjaan ekstra (mengubah callback ke lambda yang mengambil indeks, menyimpan hitungan yang tidak pernah digunakan). Saya mengerti itu digunakan kembali, tapi ini adalah solusi untuk hanya menggunakan forloop jadi seharusnya efisien. Ndash Cameron MacFarland Dec 29 08 at 23:20 Saya sudah mencoba beberapa variasi dalam hal ini, dan saya terus kembali ke solusi orang ini. Sekali lagi, ini adalah solusi elses seseorang. Tapi saya telah mengkompilasi kode itu ke perpustakaan kecil, dan menggunakannya secara cukup teratur. Saya akan menempelkan kodenya di sini, karena kebetulan situsnya (blog) tidak lagi ada di masa depan. (Tidak ada yang lebih buruk daripada melihat sebuah posting yang mengatakan Berikut adalah jawaban yang tepat yang Anda butuhkan, Klik, dan URL Mati.) Menjawab 17 Agustus 10 pukul 14: 10 Saya baru saja bertabrakan dengan hal ini dan perlu beberapa saat untuk menyelesaikannya. Ternyata fakta bahwa saya sedang membangun kueri saya di bagian menggunakan catatan 500k berukuran IEnumerable sedang diambil (lambat) lalu dikelompokkan dalam memori. Mengubahnya untuk menggunakan IQueryable saat membangun kueri, kelompok dengan dieksekusi di server dan saya hanya mendapat setengah lusin baris jumlah yang saya harapkan. Ndash Dave Downs 20 Mei pukul 18:26 Saya hanya ingin mengungkapkan seberapa mudah jawaban Anda terbaca. Saya membaca tiga artikel di google sebelum menemukan penjelasan sederhana yang mudah dipahami dan sederhana tentang perbedaannya. Terima kasih 1 ndash Chev 13 Jan 11 di 17:24 Alasan lain untuk memilih IEnumerable untuk IQueryable adalah bahwa tidak semua operasi LINQ didukung oleh semua penyedia LINQ. Jadi selama Anda tahu apa yang Anda lakukan, Anda dapat menggunakan IQueryable untuk mendorong sebanyak kueri ke penyedia LINQ (LINQ2SQL, EF, NHibernate, MongoDB, dsb.). Tetapi jika Anda membiarkan kode lain melakukan apa pun yang diinginkan dengan IQueryable Anda, akhirnya Anda akan mendapat masalah karena beberapa kode klien di suatu tempat menggunakan operasi yang tidak didukung. Saya setuju dengan rekomendasi untuk tidak merilis Quinto IQueryable dengan wildquot melewati repositori atau lapisan setara. Ndash Avish 2 Februari 14 di 19:19 Jawaban teratas bagus tapi tidak menyebutkan pohon ekspresi yang menjelaskan bagaimana kedua antarmuka berbeda. Pada dasarnya, ada dua kumpulan ekstensi LINQ yang identik. Dimana (), Sum (), Count (), FirstOrDefault (), dll semuanya memiliki dua versi: yang menerima fungsi dan fungsi yang menerima ungkapan. Tanda tangan IEnumerable version adalah: Where (FuncltCustomer, boolgt predicate) Tanda tangan versi IQueryable adalah: Where (ExpressionltFuncltCustomer, boolgtgt predicate) Anda mungkin telah menggunakan keduanya tanpa menyadarinya karena keduanya disebut menggunakan sintaks identik: mis. Di mana (x gt x. City ltCitygt) bekerja pada kedua IEnumerable dan IQueryable Bila menggunakan Where () pada koleksi IEnumerable, compiler melewatkan sebuah fungsi yang dikompilasi ke Where () Saat menggunakan Where () pada koleksi IQueryable, compiler melewati sebuah ekspresi Pohon ke mana (). Pohon ekspresi seperti sistem pantulan namun untuk kode. Kompilator mengubah kode Anda menjadi struktur data yang menjelaskan kode Anda dalam format yang mudah dicerna. Mengapa repot-repot dengan pohon ekspresi ini saya hanya ingin Where () untuk memfilter data saya. Alasan utamanya adalah baik ORM EF dan LINQ2SQL dapat mengubah pohon ekspresi secara langsung menjadi SQL dimana kode Anda akan berjalan lebih cepat. Oh, itu terdengar seperti dorongan kinerja bebas, haruskah saya menggunakan AsQueryable () di semua tempat dalam kasus itu Tidak ada IQueryable yang hanya berguna jika penyedia data yang mendasarinya dapat melakukan sesuatu dengannya. Mengubah sesuatu seperti Daftar Biasa menjadi IQueryable tidak akan memberi Anda keuntungan apa pun. Keduanya akan memberikan eksekusi ditangguhkan, ya. Seperti yang lebih disukai dari yang lain, itu tergantung pada sumber data dasar Anda. Kembali IEnumerable secara otomatis akan memaksa runtime untuk menggunakan LINQ to Objects untuk query koleksi Anda. Mengembalikan IQueryable (yang menerapkan IEnumerable, omong-omong) menyediakan fungsionalitas ekstra untuk menerjemahkan kueri Anda ke dalam sesuatu yang mungkin berkinerja lebih baik pada sumber yang mendasarinya (LINQ to SQL, LINQ to XML, etc.). Ya, keduanya menggunakan eksekusi ditangguhkan. Mari kita menggambarkan perbedaan menggunakan profiler SQL Server. Ketika kita menjalankan kode berikut: Di SQL Server profiler kita menemukan perintah yang sama dengan: kira-kira membutuhkan waktu 90 detik untuk menjalankan blok kode tersebut pada tabel WebLog yang memiliki 1 juta catatan. Jadi, semua catatan tabel dimuat ke memori sebagai objek, dan kemudian dengan masing-masing. Di mana () itu akan menjadi filter lain dalam memori terhadap benda-benda ini. Ketika kita menggunakan IQueryable dan bukan IEnumerable pada contoh di atas (baris kedua): Pada SQL Server profiler kita menemukan perintah yang sama dengan: kira-kira membutuhkan empat detik untuk menjalankan blok kode ini dengan menggunakan IQueryable. IQueryable memiliki properti yang disebut Expression yang menyimpan ekspresi pohon yang mulai dibuat saat kami menggunakan hasilnya di contoh kami (yang disebut eksekusi ditangguhkan), dan pada akhirnya ungkapan ini akan dikonversi ke kueri SQL untuk berjalan di mesin database. . Menjawab 8 Jun 14 pada 1:11 Secara umum saya akan merekomendasikan hal berikut: Untuk mengembalikan IQueryableltT jika Anda ingin mengaktifkan pengembang menggunakan metode Anda untuk memperbaiki kueri yang Anda kembali sebelum mengeksekusi. Jika Anda ingin hanya mengangkut satu set Objek untuk dihitung, cukup gunakan IEnumerable. Bayangkan sebuah IQueryable seperti apa adanya, kueri untuk data (yang dapat Anda perbaiki jika Anda mau) IEnumerable adalah seperangkat objek (yang telah diterima atau telah dibuat) yang dapat Anda perhitungkan. Jawab 11 Apr 12 12 pada 13:09 quotCan enumerate, quot not quotcan IEnumerable. quot ndash Casey 12 Feb 14 at 18:23 Ada sebuah posting blog dengan contoh kode sumber singkat tentang bagaimana penyalahgunaan IEnumerableltTgt dapat secara dramatis mempengaruhi kinerja query LINQ: Entity Framework : IQueryable vs IEnumerable. Jika kita menggali lebih dalam dan melihat ke sumbernya, kita dapat melihat bahwa ada beberapa metode penyuluhan yang berbeda yang dibuat untuk IEnumerableltTgt: Yang pertama mengembalikan enumerable iterator, dan yang kedua menciptakan query melalui penyedia query, yang ditentukan dalam sumber IQueryable. Banyak yang telah dikatakan sebelumnya, namun kembali ke akar, dengan cara yang lebih teknis: IEnumerable adalah kumpulan objek dalam memori yang dapat Anda perhitungkan - urutan dalam memori yang memungkinkan iterasi melalui (membuatnya mudah bagi Dalam foreach loop, meskipun Anda bisa pergi dengan IEnumerator saja). Mereka berada dalam ingatan sebagaimana adanya. IQueryable adalah pohon ekspresi yang akan diterjemahkan ke sesuatu yang lain pada suatu saat dengan kemampuan untuk menghitung hasil akhir. Saya rasa inilah yang membingungkan kebanyakan orang. Mereka jelas memiliki konotasi yang berbeda. IQueryable mewakili pohon ekspresi (query, sederhana) yang akan diterjemahkan ke sesuatu yang lain oleh penyedia permintaan yang mendasari begitu API rilis dipanggil, seperti fungsi agregat LINQ (Sum, Count, etc.) atau ToListArray, Dictionary. . Dan benda IQueryable juga menerapkan IEnumerable. IEnumerableltTgt sehingga jika mereka mewakili kueri hasil kueri tersebut dapat diiterasi. Artinya IQueryable tidak harus menjadi pertanyaan saja. Istilah yang tepat adalah pohon ekspresi. Sekarang bagaimana ekspresi tersebut dieksekusi dan apa yang mereka lakukan adalah semuanya tergantung pada penyedia permintaan yang disebut (pelaksana ekspresi yang dapat kita pikirkan). Di dunia Entity Framework (yang merupakan penyedia sumber data mistik yang mendasari, atau penyedia kueri) Ungkapan IQueryable diterjemahkan ke dalam kueri T-SQL asli. Nhibernate melakukan hal yang sama dengan mereka. Anda dapat menulis konsep Anda sendiri yang sesuai dengan konsep yang dijelaskan dengan baik di LINQ: Buatlah tautan Penyedia IQueryable, misalnya, dan Anda mungkin ingin memiliki API kueri khusus untuk layanan penyedia toko produk Anda. Jadi pada dasarnya, benda-benda IQueryable mulai dibangun sepanjang perjalanan panjang sampai kita secara eksplisit melepaskannya dan memberi tahu sistem untuk menuliskannya kembali ke SQL atau apa pun dan mengirim rantai eksekusi untuk diproses selanjutnya. Seolah-olah untuk eksekusi ditangguhkan dengan fitur LINQ untuk menahan skema pohon ekspresi di memori dan mengirimkannya ke eksekusi hanya sesuai permintaan, kapan pun API tertentu dipanggil terhadap urutannya (Count, ToList, dll. Yang sama). Penggunaan keduanya sangat tergantung pada tugas yang Anda hadapi untuk kasus tertentu. Untuk pola repositori yang terkenal, saya secara pribadi memilih untuk mengembalikan IList. Itu adalah IEnumerable over Lists (pengindeks dan sejenisnya). Jadi, saran saya untuk menggunakan IQueryable hanya di dalam repositori dan IEnumerable di tempat lain dalam kode. Tidak mengatakan tentang masalah testability yang IQueryable rusak dan menghancurkan prinsip pemisahan perhatian. Jika Anda mengembalikan ekspresi dari dalam repositori, konsumen mungkin bermain dengan lapisan ketekunan sesuai keinginan. Sedikit tambahan untuk kekacauan :) (dari diskusi di komentar)) Tak satu pun dari mereka adalah objek dalam memori karena mereka bukan tipe sebenarnya per, mereka adalah spidol tipe - jika Anda ingin melangkah sejauh itu. Tapi itu masuk akal (dan itulah mengapa bahkan MSDN mengatakannya seperti ini) untuk memikirkan IEnumerables sebagai koleksi memori sementara IQueryables sebagai pohon ekspresi. Intinya adalah bahwa antarmuka IQueryable mewarisi antarmuka IEnumerable sehingga jika itu mewakili kueri, hasil kueri tersebut dapat dihitung. Enumerasi menyebabkan pohon ekspresi dikaitkan dengan objek IQueryable yang akan dieksekusi. Jadi, sebenarnya, Anda benar-benar tidak dapat memanggil anggota IEnumerable apapun tanpa memiliki objek dalam memori. Ini akan masuk ke sana jika Anda melakukannya, anyways, jika tidak kosong. IQueryables hanya pertanyaan, bukan data. Dijawab 5 Jun 14 at 16:23 Komentar bahwa IEnumerables selalu di-memori tidak benar benar. Antarmuka IQueryable mengimplementasikan antarmuka IEnumerable. Karena ini, Anda bisa melewati IQueryable mentah yang mewakili kueri LINQ-to-SQL langsung ke tampilan yang mengharapkan IEnumerable Anda mungkin akan terkejut saat mengetahui bahwa konteks data Anda telah kedaluwarsa atau Anda akhirnya mengalami masalah dengan MARS ( Beberapa set hasil aktif). Ndash Alexander Pritchard 22 Jan 15 at 20:13 Jadi, sebenarnya, Anda benar-benar bisa memanggil anggota IEnumerable tanpa memiliki objek dalam memori. Ini akan masuk ke sana jika Anda melakukannya, anyways, jika tidak kosong. IQueryables hanya pertanyaan, bukan data. Tapi aku benar-benar mengerti maksudmu. Aku akan menambahkan komentar tentang ini. Ndash Arman McHiter Feb 4 15 di 10:58 AlexanderPritchard tidak satupun dari mereka adalah objek yang diingat karena mereka bukan tipe sebenarnya, mereka adalah spek dari tipe - jika Anda ingin melangkah sejauh itu. Tapi itu masuk akal (dan itu sebabnya bahkan MSDN mengatakannya seperti ini) untuk memikirkan IEnumerables sebagai koleksi memori sementara IQueryables sebagai pohon ekspresi. Intinya adalah bahwa antarmuka IQueryable mewarisi antarmuka IEnumerable sehingga jika itu mewakili kueri, hasil kueri tersebut dapat dihitung. Enumerasi menyebabkan pohon ekspresi dikaitkan dengan objek IQueryable yang akan dieksekusi. Ndash Arman McHiter Feb 4 15 at 11:02 Saya baru-baru ini mengalami masalah dengan IEnumrable v. IQueryable. Algoritma yang digunakan pertama kali melakukan query IQueryable untuk mendapatkan satu set hasil. Ini kemudian diteruskan ke loop foreach, dengan item yang diberikan sebagai kelas EF. Kelas EF ini kemudian digunakan dalam klausa kuadran Linq to Entity, sehingga hasilnya menjadi IEnumerable. Saya cukup baru mengenal EF dan Linq untuk Entitas, jadi butuh beberapa saat untuk mencari tahu hambatannya. Dengan menggunakan MiniProfiling, saya menemukan kueri dan kemudian mengkonversikan semua operasi individual ke kueri IQueryable Linq untuk Entitas. The IEnumerable mengambil 15 detik dan IQueryable mengambil 0,5 detik untuk mengeksekusi. Ada tiga tabel yang terlibat dan, setelah membaca ini, saya percaya bahwa kueri IEnumerable sebenarnya membentuk tiga tabel cross-product dan memfilter hasilnya. Cobalah untuk menggunakan IQueryables sebagai aturan praktis dan rencanakan pekerjaan Anda untuk membuat perubahan Anda terukur. Dijawab 12 Jul 12 at 20:39 alasannya adalah bahwa ekspresi IQueryable dikonversi ke SQL asli di EF dan dijalankan tepat di DB sementara daftar IEnumerable berada di memori objek. Mereka diambil dari DB di beberapa titik saat Anda memanggil fungsi agregat seperti Count, Sum, atau To. Dan beroperasi di memori sesudahnya. IQueryable s juga terjebak dalam memori begitu Anda pernah memanggil salah satu API itu, tapi jika tidak, Anda bisa menyampaikan ungkapan di atas tumpukan lapisan dan bermain-main dengan filter sampai panggilan API. DAL yang dirancang dengan baik sebagai Repositori yang dirancang dengan baik akan memecahkan masalah semacam ini) ndash Arman McHiter, 5 Jun 14 14 pada 15:29 Saya ingin mengklarifikasi beberapa hal karena tanggapan yang tampaknya bertentangan (kebanyakan seputar IEnumerable). (1) IQueryable memperluas antarmuka IEnumerable. (Anda dapat mengirim IQueryable untuk sesuatu yang mengharapkan IEnumerable tanpa kesalahan.) (2) Baik IQueryable dan IEnumerable LINQ mencoba pemuatan malas saat iterasi melebihi hasil yang ditetapkan. (Perhatikan bahwa implementasi dapat dilihat pada metode ekstensi antarmuka untuk setiap jenis.) Dengan kata lain, IEnumerables tidak eksklusif dalam memori. IQueryables tidak selalu dijalankan pada database. IEnumerable harus memuat barang ke memori (sekali diambil, mungkin malas) karena tidak memiliki penyedia data abstrak. IQueryables bergantung pada penyedia abstrak (seperti LINQ-to-SQL), walaupun ini juga bisa menjadi penyedia memori. (A) Ambil daftar catatan sebagai IQueryable dari konteks EF. (Tidak ada catatan yang di-memori.) (B) Lulus IQueryable ke tampilan yang modelnya adalah IEnumerable. (Valid IQueryable meluas IEnumerable.) (C) Iterasi dan akses catatan kumpulan data, entitas anak dan properti dari tampilan. (Dapat menyebabkan pengecualian) (1) Upaya IEnumerable memuat malas dan konteks data Anda kadaluarsa. Pengecualian dilontarkan karena provider sudah tidak lagi tersedia. (2) Entitas entitas proxy entitas diaktifkan (default), dan Anda mencoba mengakses objek (virtual) terkait dengan konteks data yang kedaluwarsa. Sama seperti (1). (3) Multiple Active Result Sets (MARS). Jika Anda mengulangi IEnumerable di blok foreach (var record di resultSet) dan sekaligus mencoba mengakses record. childEntity. childProperty. Anda mungkin berakhir dengan MARS karena pemuatan malas dari kumpulan data dan entitas relasional. Ini akan menyebabkan pengecualian jika tidak diaktifkan dalam string koneksi Anda. Saya telah menemukan bahwa memungkinkan MARS dalam string koneksi bekerja dengan tidak baik. Saya sarankan Anda menghindari MARS kecuali jika dipahami dengan baik dan secara eksplisit diinginkan. Jalankan query dan simpan hasilnya dengan cara meminta resultList resultsSet. ToList () Hal ini tampaknya merupakan cara paling mudah untuk memastikan entitas Anda berada dalam memori. Jika Anda mengakses entitas terkait, Anda mungkin masih memerlukan data konteks. Entah itu, atau Anda dapat menonaktifkan proxy entitas dan secara eksplisit Sertakan entitas terkait dari DbSet Anda. Perbedaan utama antara IEnumerable dan IQueryable adalah tentang di mana logika filter dieksekusi. Satu mengeksekusi pada sisi klien (dalam memori) dan yang lainnya dijalankan pada database. Sebagai contoh, kita dapat mempertimbangkan contoh di mana kita memiliki 10.000 catatan untuk pengguna di database kami dan katakanlah hanya 900 yang merupakan pengguna aktif, jadi dalam kasus ini jika kita menggunakan IEnumerable maka pertama-tama memuat 10.000 catatan di memori dan kemudian berlaku Filter IsActive di atasnya yang akhirnya mengembalikan 900 pengguna aktif. Sementara di sisi lain pada kasus yang sama jika kita menggunakan IQueryable maka akan langsung mengaplikasikan filter IsActive pada database yang langsung dari sana akan mengembalikan 900 pengguna aktif. Jawab 9 Mei jam 12:03 jadi mana yang bagus untuk digunakan. Di mana skenario Ndash Neo Jan 23 at 9:08 Kita bisa menggunakan keduanya dengan cara yang sama, dan itu hanya berbeda dalam performa. IQueryable hanya menjalankan terhadap database dengan cara yang efisien. Ini berarti bahwa itu menciptakan keseluruhan permintaan pilih dan hanya mendapatkan catatan terkait. Misalnya, kita ingin mengambil 10 besar pelanggan yang namanya diawali dengan Nimal. Dalam kasus ini, query pilih akan dihasilkan sebagai pilih top 10 dari Customer dimana nama seperti Nimal. Tapi jika kita menggunakan IEnumerable, querynya akan seperti pilih dari Customer dimana nama seperti Nimal dan sepuluh besar akan disaring pada tingkat pengkodean C (semua catatan pelanggan dari database dan meneruskannya ke C). Menjawab 25 Mar 16 at 7:02 Saat menggunakan LINQ untuk Entitas, penting untuk memahami kapan harus menggunakan IEnumerable dan IQueryable. Jika kita menggunakan IEnumerable, query akan segera dieksekusi. Jika kita menggunakan IQueryable, eksekusi query akan ditangguhkan sampai aplikasi meminta pencacahan. Sekarang mari kita lihat apa yang harus dipertimbangkan saat memutuskan apakah akan menggunakan IQueryable atau IEnumerable. Menggunakan IQueryable memberi Anda kesempatan untuk membuat query LINQ yang kompleks dengan menggunakan beberapa pernyataan tanpa mengeksekusi query pada tingkat database. Kueri hanya akan dijalankan bila kueri LINQ terakhir dicacah. Jawab Jul 10 15 at 16:34 Keduanya IQueryable dan IEnumerable menunda eksekusi. Perbedaannya adalah apakah pekerjaan dilakukan di DB atau di memori, bukan saat selesai. Ndash Servy Jul 10 15 at 16:45 Jawaban Anda 2017 Stack Exchange, IncPersonally, saya pikir kemampuan untuk mengakui dan menghadapi kesalahan Anda adalah efek samping yang berharga untuk memperoleh pengalaman dan kepercayaan sebagai pengembang. Saya tidak bisa membantu Anda keluar dari Penjara Sindrom Jantung8221 per se, tapi saya dapat mengatakan kepada para pengembang muda bahwa Anda bisa lebih optimis mengenai kesalahan yang Anda buat dalam pengambilan keputusan teknis Anda begitu Anda terlalu berpikir bahwa Anda perlu membuktikannya. Layak untuk semua orang di sekitar Anda setiap saat. Pos ini mungkin tidak lain hanyalah tatapan pusar, tapi saya yakin ada sesuatu di sini yang akan berhubungan dengan kebanyakan pengembang lebih cepat atau lambat. Saya telah mengalami beberapa kesalahan ini di wajah saya minggu ini jadi ini sudah ada di pikiran saya. Beberapa tahun yang lalu saya akan mengatakan bahwa kesalahan terbesar saya adalah kegagalan untuk menyediakan dokumentasi dan contoh penggunaan yang memadai. Hari ini aku akan dengan senang hati menempatkan Marten. StructureMap. Atau dokumentasi pendengaran terhadap hampir semua proyek OSS, jadi saya akan merasa bersalah atas dosa-dosa masa lalu itu. Don8217t Fly Solo di Hal-Hal Besar Saya pikir itu mungkin untuk bekerja sendiri di perpustakaan kecil mandiri. Jika Anda mencoba melakukan sesuatu yang besar, Anda akan membutuhkan bantuan dari orang lain. Idealnya, Anda pasti memerlukan bantuan pengkodean dan pengujian aktual, namun setidaknya Anda memerlukan masukan dan gagasan fitur dari orang lain. Jika Anda memiliki keinginan untuk melihat proyek Anda menarik penggunaan yang cukup besar, Anda pasti menginginkan orang lain yang juga diinvestasikan untuk melihat keberhasilan proyek Anda. Saya tidak bisa banyak membantu Anda dalam hal bagaimana menyelesaikan keseluruhan masalah ini. Selain Marten, saya tidak pernah berhasil membantu menumbuhkan komunitas di sekitar alat yang telah saya bangun. FubuMVC memang memiliki komunitas yang hebat pada awalnya, tapi saya lebih memaknai Chad Myers dan Josh Arnold daripada yang saya lakukan saat itu. Berpikir bahwa Waktu adalah Linier Setiap saat saya membuat rilis StructureMap, saya merasa seperti saat itu, akhirnya saya selesai mengerjakan hal ini, dan saya dapat beralih ke hal-hal lain sekarang.8221 Saya pikir rilis 3.0 akan menyelesaikan secara permanen yang terburuk. Dari struktur struktural dan kinerja cacat. Kemudian datanglah ASP Core, CoreCLR, dan keinginan untuk mempercepat waktu bootstrap aplikasi kita, jadi keluarlah StructureMap 4.0 8212 dan kali ini saya benar-benar selesai, terima kasih. Kecuali aku tidak. Pengguna menemukan bug baru dari kasus penggunaan yang tidak pernah dipertimbangkan (dan bagaimanapun juga akan digunakan, tapi saya ngelantur). Corey Kaylor dan saya akhirnya melakukan beberapa optimasi kinerja untuk StructureMap akhir tahun lalu yang membatalkan beberapa masalah dengan StructureMap dalam kombinasi dengan beberapa alat yang kami gunakan. Baru Senin ini saya menghabiskan 3-4 jam menangani bug yang beredar dan menarik permintaan untuk mengeluarkan sebuah rilis baru. Maksud saya di sini adalah mengadopsi pola pikir bahwa aktivitas Anda pada proyek OSS bersifat siklis, tidak linier. Sistem perangkat lunak, kerangka kerja, atau perpustakaan tidak pernah selesai, hanya ditinggalkan. Ini adalah kesalahan terbesar saya, dan ini benar-benar masalah perspektif. Jadilah Realistis tentang Pengguna Pendukung Saya selalu memiliki masalah dari waktu ke waktu di StructureMap ketika saya merasa bahwa saya terlalu terbelakang dengan pertanyaan dan masalah pengguna dengan campuran rasa bersalah dan frustrasi. Saya pikir satu-satunya jawaban sebenarnya adalah bersikap realistis tentang seberapa cepat Anda bisa berkeliling untuk menangani masalah pengguna dan mengurangi kelemahan Anda sendiri. Keluarga Anda, tempat kerja Anda, dan Anda harus menjadi prioritas yang lebih tinggi daripada seseorang di internet. Fitur Bangunan Terlalu Awal Pada hari-hari awal pengembangan Agile kita berbicara sedikit tentang pendekatan 8220pull8221 vs 8220push8221 untuk lingkup proyek. Dengan gaya 8220push8221, Anda mencoba untuk merencanakan terlebih dahulu fitur dan infrastruktur apa yang akan Anda butuhkan, dan bangun lebih awal. Dengan gaya 8220pull8221, Anda menunda pengenalan infrastruktur atau fitur baru sampai ada kebutuhan yang ditunjukkan untuk itu. Pengalaman saya yang konsisten selama dekade terakhir adalah bahwa fitur yang saya bangun sebagai reaksi terhadap kebutuhan pasti akan sebuah proyek yang sedang berjalan di tempat kerja telah jauh lebih berhasil daripada gagasan yang saya hadapi dalam proyek OSS saya karena kedengarannya keren saat itu. Dogfooding Cobalah untuk tidak memasukkan apapun ke sana untuk dikonsumsi orang lain jika Anda tidak menggunakannya sendiri dalam situasi realistis. Saya mungkin melontarkan pistol pada rilis Storyteller 4.0 dan saya perlu mendorong rilis baru minggu depan untuk masalah kegunaan dan beberapa bug. Semua stres itu bisa dihindari jika saya hanya menggunakan alpha8217s di lebih banyak proyek saya sendiri sebelum memotong nuget. Di sisi lain, terkadang yang paling Anda butuhkan adalah umpan balik dari orang lain. Saya ingin tahu apakah saya membuat kesalahan dengan menambahkan fungsi sumber acara ke Marten. Proyek yang ada dalam pikiran saya yang akan menggunakannya di tempat kerja telah ditunda tanpa batas waktu dan saya tidak benar-benar meniru semuanya. Untungnya, banyak orang lain telah menggunakannya dalam skenario realistis dan saya hampir sepenuhnya bergantung pada mereka untuk menemukan masalah atau menyarankan peningkatan atau perubahan API. Saya pikir fungsi itu akan meningkat jauh lebih cepat jika saya adalah satu-satunya dogfooding itu, tapi itu tidak akan terjadi dalam waktu dekat. Tinjauan Permintaan Tarik yang Tidak Memadai Saya mencoba berbuat salah saat mengajukan permintaan lebih cepat daripada nanti, dan ini sering menyebabkan masalah di jalan. Di satu sisi, lebih sulit memproses kode dari orang lain untuk fitur baru karena Anda tidak diinvestasikan untuk melihat jalan Anda melalui implikasi dan potensi gotchas. Saya melihat permintaan tarik yang dilengkapi dengan tes yang memadai dan saya cenderung menerimanya. Sudah beberapa kali saya merasa lebih baik berhenti dan memikirkan bagaimana hal itu sesuai dengan sisa proyek. Saya tidak tahu jawaban yang tepat di sini. Terlalu ketat persyaratan untuk menarik permintaan dan Anda tidak akan mendapatkan apapun. Terlalu sedikit pengawasan mengarah pada Anda mendukung kode orang lain. Overreach dan Hubris Saya benci mengatakan bahwa Anda seharusnya tidak mengejar impian OSS Anda, tapi saya pikir Anda harus berhati-hati untuk tidak menjangkau atau melakukan misi yang tidak mungkin. Mengambil flameout spektakuler saya dengan proyek FubuMVC sebagai contoh, saya pikir saya sendiri membuat kesalahan ini: Menjadi terlalu muluk. Pengembangan perangkat lunak dan layanan bus alternatif yang sama sekali alternatif dengan konsep modularitasnya sendiri yang jauh di luar arus utama tidak akan pernah terbang. Saya pikir Anda lebih mungkin berhasil dengan menjadi bagian dari ekosistem yang ada daripada mencoba menciptakan ekosistem baru. Kurasa maksudku adalah bahwa hanya akan ada banyak DHH8217 atau John Resig8217s. Membangun infrastruktur yang tidak berhubungan langsung dengan inti proyek Anda. FubuMVC pada akhirnya termasuk mesin templating proyeknya sendiri, middleware file statis, penyedia Saml2, dan berbagai kemampuan lain yang bisa saya tarik dari rak dan bukan membangun diri. Semua barang tambahan tersebut merupakan biaya peluang yang sangat besar bagi diri saya sendiri. Cukup banyak membangun terlalu banyak barang daripada berfokus pada peningkatan inti proyek Anda Meskipun ini adalah demonstrasi kerja di kotak saya, yang ditunjukkan oleh I8217m di sini adalah pendekatan konseptual yang sangat awal untuk ditinjau oleh orang lain di toko saya. Saya senang memiliki umpan balik mengenai hal ini. Saya menghabiskan cukup banyak waktu di kantor Salt Lake City minggu lalu untuk berbicara dengan orang-orang QA kami tentang otomatisasi tes secara umum dan di mana Selenium melakukan atau tidak sesuai dengan pendekatan kami (yang diinginkan). Para pengembang di toko saya menggunakan Selenium cukup sedikit hari ini di dalam suite penerimaan Storyteller kami dengan hasil yang beragam, namun sekarang orang QA kami ingin mengotomatisasi beberapa rangkaian uji manual mereka dan menendang ban di Selenium. Sebagai tindak lanjut dari diskusi tersebut, tulisan ini menunjukkan konsep awal tentang bagaimana kita dapat menggunakan fungsi Selenium dalam spesifikasi Storyteller untuk umpan balik mereka dan umpan balik Anda. Semua kodenya ada di cabang Storyteller8217s 4.1. Demo Specification Let8217s mulai sangat kasar. Let8217s mengatakan bahwa Anda memiliki halaman web yang memiliki tag dengan beberapa jenis teks pesan pengguna yang pertama kali disembunyikan pada awalnya. Lebih dari itu, mari kita katakan bahwa Anda memiliki dua tombol di layar dengan teks 8220Show8221 dan 8220Hide.8221 Spesifikasi Storyteller untuk perilaku itu mungkin terlihat seperti ini: dan hasil HTML akan terlihat seperti ini: Runtime 3 detik sebagian besar ada di Pembuatan dan peluncuran contoh browser Chrome. Lebih lanjut tentang ini nanti. Untuk menerapkan spesifikasi ini, kita memerlukan dua hal, kelas Fixture yang menerapkan bahasa yang diinginkan dan data spesifikasi aktual dalam file penurunan nilai yang ditunjukkan pada bagian berikutnya. Dalam contoh ini, akan ada perpustakaan 8220Storyteller. Selenium8221 baru yang memberikan dasar untuk mengintegrasikan Selenium ke dalam spesifikasi Storyteller dengan kelas dasar 8220ScreenFixture 8221 untuk Fixture8217s yang menargetkan Selenium. Setelah itu, kelas SampleFixture yang digunakan dalam spesifikasi di atas terlihat seperti ini: Jika Anda mengedit spesifikasi di editor Spesifikasi Storyteller8217s. Anda akan memiliki kotak drop-down yang mencantumkan elemen dengan nama tempat mana pun yang Anda perlukan untuk menentukan elemen seperti ini: Akhirnya, paket Storyteller. Selenium yang diusulkan menambahkan informasi ke kinerja yang direkam untuk berapa lama halaman web dibutuhkan untuk dimuat. Ini adalah waktu menurut WebDriver dan seharusnya tidak digunakan untuk optimasi kinerja yang mendetail, namun angka ini masih berguna untuk memahami masalah kinerja selama eksekusi spesifikasi Storyteller. Lihat baris 8220Navigationsimple. htm8221 di bawah ini: Seperti apa spesifikasi sebenarnya Jika Anda menulis spesifikasi di atas di antarmuka pengguna Storyteller, Anda bisa mendapatkan file penurunan ini: Namun, jika Anda menulis spesifikasi dengan tangan langsung di file penurunan, Anda Dapat menyederhanakannya dengan ini: Kami berusaha sangat keras dengan Storyteller 4 untuk membuat spesifikasi lebih mudah ditulis untuk non-pengembang dan apa yang Anda lihat di atas adalah produk dari usaha itu. Mengapa Penutur Selenium bukan hanya Selenium mengapa Anda ingin menggunakan Storyteller dan Selenium bersama-sama, bukan hanya Selenium dengan sendirinya Beberapa alasan: Ada banyak hal yang terjadi dalam tes otomatis yang efektif selain mengarahkan browser web (menyiapkan data sistem, memeriksa data sistem , Memulai sistem yang sedang diuji). Storyteller menyediakan lebih banyak fungsi daripada Selenium dengan sendirinya. Ini sangat berharga untuk mengekspresikan tes otomatis dalam bahasa tingkat tinggi dengan sesuatu seperti Storyteller atau Cucumber daripada langsung ke elemen layar dan detail pelaksanaan lainnya. Saya katakan ini sebagian karena membuat spesifikasi lebih mudah dibaca manusia, tapi juga untuk memisahkan ekspresi tes dari rincian implementasi yang mendasarinya. Anda ingin melakukan ini agar tes Anda lebih mudah mengakomodasi perubahan struktural pada halaman web. Jika Anda tidak pernah mengerjakan pengujian otomatis berskala besar melawan browser web, Anda harus sadar bahwa jenis tes ini bisa sangat rapuh dalam menghadapi perubahan antarmuka pengguna. Pendongeng menyediakan banyak instrumentasi dan kinerja tambahan yang bisa sangat berguna untuk debugging pengujian atau masalah kinerja Saya benci membuang yang ini di luar sana, namun kemampuan teruji Storyteller8217 yang dapat dikonfigurasi dalam integrasi berkelanjutan sangat berguna untuk suite uji dengan jumlah besar sekali jumlah perilaku asinkron seperti Anda sering bertemu dengan aplikasi web modern Karena seseorang akan bertanya, atau penggemar F pasti akan membuang ini dari sana, ya, kanopi juga bagus yang menggabungkan DSL yang bagus di sekitar Selenium dan menyediakan beberapa stabilisasi. I8217m tidak meremehkan kanopi sedikit pun, tapi semua yang saya katakan tentang penggunaan Selenium mentah berlaku sama untuk menggunakan Canopy dengan sendirinya. Untuk menjadi sedikit lebih eye-poky tentang hal itu, salah satu kisah sukses pertama Storyteller 3 adalah mengganti test suite yang sangat tidak stabil yang menggunakan Canopy secara naif. Storyteller adalah proyek yang telah lama berjalan untuk merancang spesifikasi yang dapat dibaca manusia dan dapat dieksekusi untuk proyek. Rilis 4.0 yang baru dimaksudkan agar Pengarang Story lebih mudah digunakan dan dikonsumsi untuk orang non teknis dan untuk meningkatkan kemampuan pengembang untuk memecahkan masalah kegagalan spesifikasi. Setelah sekitar 5 bulan usaha, akhirnya saya bisa memotong 4.0 Nugets untuk Storyteller pagi ini dan update dokumentasi terbaru. Jika Anda benar-benar baru mengenal Storyteller, lihat halaman awal atau siaran web ini. Jika Anda berasal dari Storyteller 3.0, ketahuilah bahwa Anda perlu terlebih dahulu mengubah spesifikasi Anda ke format 4.0 yang baru. API Percobaan Storyteller tidak mengalami perubahan yang mencolok, namun langkah bootstrap sedikit berbeda untuk mengakomodasi CLI dotnet. Anda bisa melihat seluruh daftar perubahan di sini. Atau sorotan utama dari rilis ini adalah: CoreclR Support Storyteller 4.0 dapat digunakan pada 4.6 proyek atau proyek yang menargetkan CoreCLR. Sampai sekarang, Storyteller sekarang menjadi alat cross platform. Anda dapat membaca lebih lanjut tentang pengalaman saya yang mendongak Storyteller ke CoreCLR di sini. Merangkul CLI dotnet. Saya suka dotnet baru dan berharap bisa melakukannya bertahun-tahun yang lalu. Ada sebuah paket pendaratan CLI 8220dotnet8221 CLI yang menggantikan alat utilitas ST. exe lama di 3.0 yang seharusnya lebih mudah dipasang untuk pengguna baru. Penurunan harga di mana-mana Storyteller 4.0 mengubah format spesifikasi menjadi format penurunan harga. Menambahkan kemampuan baru untuk merancang dan menghasilkan Fixture8217s dengan penurunan harga. Dan Anda dapat dengan senang hati menggunakan teks marka sebagai prosa sesuai spesifikasi untuk meningkatkan kemampuan Anda dalam mengkomunikasikan niat dalam spesifikasi Storyteller. Mode Peluncuran. Tes integrasi bisa sangat sulit untuk debug ketika mereka gagal. Untuk mengurangi beban, Storyteller 4.0 menambahkan mode Stepthrough baru yang memungkinkan Anda berjalan secara manual melalui semua langkah dari spesifikasi Storyteller sehingga Anda dapat memeriksa keadaan terkini dari sistem yang sedang diuji sebagai bantuan dalam pemecahan masalah. 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. Yaitu. 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. Posting navigasi

No comments:

Post a Comment