私はビジネスアプリケーションの伝統的なアーキテクチャに悩まされています-私はすでにこれについて話しました。私は批判します-私は提案します。さて、前回の記事から問題の解決策を探したことが私を導いた場所をお話しします。
私は建築の概念を繰り返すのが好きです。私は一生、アーキテクチャとソフトウェア設計の分野で機能し、同時にシンプルなものを見つけようとしてきました。それは理解のための脳の休憩と根本的なパラダイムシフトを必要としません。多くのアイデアが蓄積されており、私はそれらの最高のものを私のフレームワークであるReinforced.Tectureに組み合わせることにしました。そのようなものを開発することは、考えるための膨大な量の食べ物です、私はそれらを共有したいと思います。
そのような技術的なことについてのテキストは、通常、ひどく退屈です。私は正直に退屈しないように努めたので、私のテキストは少し攻撃的であることがわかりました。これらのルールを使用した.NETアプリケーションのアーキテクチャについて読むことに興味がある場合は、にアクセスしてください。
: , , - . ( ), , — . . Tecture , . DevRel open source , . , , ( MIT-). , - — .
: . , , , . , . : , , , , , "-" . :
- - Java (, C#) 80-90. — MS- eShopOnContainers, , - -. , peer review ;
- . — , , .
"", "". — . , . , .NET.
: . , 100 UpWork- MVP. , , 30 15 . , , . , production-, -. node/react . , , . long term. " , " .
外部システム
- : , — , - SalesForce. - , , , API . — -.
, — , . , , "-": , , . - — , .
: . , , . O/RM, SQL-. O/RM- . — INSERT- , . , , O/RM- : " ". , , . , . . — SaveChanges .
. , O/RM . , . — " " SQL, . , "object-relational impedance mismatch". . , : , . — , . , , . — . DBA - stored-.
. . : . , .
Tecture . , . , .
( )
, . , , . Tecture — , . — :
public interface Db { }
I
.
CodeFest- - , , — " , HKT", . , .
C# type
F# TypeScript, — interface
. type — -, type inference . , C# HKT, reflection-.
( )
. . . . O/RM, SQL-. -, , , SQL . . , -.
"", "" — . , - . AOP . Tecture , , , ? , .
. C# . :
PM> Install-Package Reinforced.Tecture.Aspects.Orm
PM> Install-Package Reinforced.Tecture.Aspects.DirectSql
public interface Db :
CommandQueryChannel <
Reinforced.Tecture.Aspects.Orm.Command,
Reinforced.Tecture.Aspects.Orm.Query>,
CommandQueryChannel <
Reinforced.Tecture.Aspects.DirectSql.Command,
Reinforced.Tecture.Aspects.DirectSql.Query>
{ }
, Tecture (, , ). by design . : netstandard2.0. — . .NET Core .
, ( ) -. , target framework netstandard2.0. . , Tecture .NET (: windows), .
, . - , .NET Framework, .
, SOLID, O/CP Separation of Concerns. .
— . , , . — . , , .
, -, . : separated contexts DDD, .
— . , - . : . - , Tecture. , .
— , -. . Tecture, :
//
public class Orders : TectureService
<
Updates<Order>, //
Adds<OrderLine> // OrderLine-
>
{
private Orders() { } // .
// . . .
// - - -
public void AddLine(int orderId, int productId, int quantity)
{
//
var order = From<Db>().Get<Order>().ById(orderId);
//
To<Db>().Update(order)
.Set(x => x.TotalQuantity, order.TotalQuantity + quantity);
//
To<Db>().Add(new OrderLine {
OrderId = orderId,
ProductId = productId,
Quantity = quantity});
// ,
Let<Products>().Reserve(productId, quantity);
} // .
}
, :
- IoC-. Let<Products>().(...)
( ). 90% IoC- ( ) , . runtime exception. , — . , .
Tecture -IoC . , . — ( ). Tecture , . . : , Tecture - .
- . , Tecture , . . : . , ISomethingService
. . , — . , ( virtual
). , .
- , , . — dll-, , . . . internal , . , : , — . , . "domains", -.
-: . , . , -:
public class Orders : TectureService < Updates<Order>, Adds<OrderLine> >
{
, . . Order- , OrderLine- ( ). , . , C# . , To<Db>().Delete(order)
— , : ", , ".
. . Updates<>
Adds<>
ORM . , , . HKT — .
— . HKT , , -. god object-. , , , . . — TectureService
, 10 . , .
-: "Service". — . .
Let<>
. ? , : Tecture IoC- ITecture
( ). ITecture TectureBuilder
. , . , . .
, ITecture
Let<>()
, . : tecture.Let<Orders>().CreateOne(...)
, ITecture
.
? , ( protected
):
Let<TService>()
, . . -:Do<>
. , -.From<TChannel>()
: , . , , ITecture;To<TChannel>()
: , . , ;
From<>
To<>
.
EntityFramework: . LINQ, SQL, , , IQueryable. ! - , -. , .Add, .Remove — … . — SaveChanges, SQL . . EF- ChangesTracker, diff, " , — " — .
— . -. , Read, Write. .
. ? - - ( ), , , . - .
— . -, , , , 10 , , ? — - .
. . , CQRS, , MediatR, DDD, "Entity Framework Core in Action" - . , . Microsoft — , , . Microsoft MVC, Model, View Controller. web-, HttpRequest
HttpResponse
. , , . . .
Tecture : , — .
( )
— From<>
.
: Tecture , — . — . . Tecture — . .
: , concern- . SELECT . . , , — . Repeatable Read. : , , , , - . C# .
fake-, Repository Pattern . . Tecture , : " " , . , — , - . . : GetSomethingById
, :
// Id-
public interface IEntity { int Id {get;} }
// IQueryable ()
public interface IQueryFor<T>
{
IQueryable<T> All { get; }
IQueryable<U> Joined<U>();
}
public static class Extensions
{
// IQueryFor
public static IQueryFor<T> Get<T>(this Read<QueryChannel<Orm.Query>> qr) where T : class
{
//
var pr = qr.Aspect();
//
return new QueryForImpl<T>(pr);
}
// ById IQueryFor<T>, T int- Id
public static T ById<T>(this IQueryFor<T> q, int id) where T : IEntity
{
return q.All.FirstOrDefault(x => x.Id == id);
}
}
, :
// , ,
var user = From<Db>().Get<User>().ById(10);
- — LINQ, fluent-, , .
( )
— From<>()
. / … , ? , To<>()
. — , . — .
To<>()
Write<...>
-, . , . .Add. . .Add
— . — .
. . Tecture Add, .
: - , , . , . EntityFramework. . .
EntityFramework, Save
ITecture
. .
? . . . , , exception- , . . , .
, . exception-, . . : - -, , , . , , , , -, e-mail- ( ). — , . .
, : . , - ? : , , Tecture . ( ORM-, Order ):
public async Task ILikeToMoveIt()
{
var newOrder = To<Db>().Add(new Order());
await Save;
var id = From<Db>().Key(newOrder);
To<Db>().Delete<Order>().ByPk(id);
}
Save- await. , !
, — . Save.ContinueWith(...)
.
, Tecture . Development Experience .
.