传统的业务应用程序体系结构使我很烦恼-我已经讨论过了。我批评-我建议。现在,我将告诉您寻找上一篇文章中的问题的解决方案的原因。
我喜欢遍历建筑概念。我一生都在尝试在架构和软件设计中找到可行且同时简单的东西。它不需要大脑的理解和彻底的范式转换。已经积累了很多想法,因此我决定在我的框架中结合最好的想法-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 .
.