Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Specification pattern implementation in C#

License

NotificationsYou must be signed in to change notification settings

bmgandre/dotnet-specification-pattern

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Specification pattern implementation in C#

Build statusBuild Status

This repository provides a C# Composite based implementation ofthe Specification pattern.

The Composite implementation adds flexibility by allowing thebusiness rules to be combined. In additional to the logicaloperations, this implementation uses a Builder pattern withFluent Interfaces. As a result, we can use extensions methods,instead of classes, to create new rules.

Comparison

The examples below compares the standard composite implementationto an implementation using the builder and fluent interfaces.

Standard implementation

In a standard implementation, the rule definition is located insidethe class:

publicclassBlogCreatedAfterSpecification:BaseSpecification<Blog>{publicBlogCreatedAfterSpecification(DateTimedateTime):base(x=>x.Created>=dateTime){}}

This is how to instantiate and build the specifications:

varcreatedAfter=newBlogCreatedAfterSpecification(dateTime);varnotBanned=newBlogNotBannedSpecification();varnotExpired=newBlogNotExpiredSpecification();varspecification=createdAfter.And(notBanned).And(notExpired);

Builder with Fluent Interfaces

Instead of a class per rule, a extension method is used to add rules.In the sample code below, Add is a method with an Expression parameter,it create an instance of the Specification and add to the compositestructure.

publicstaticclassBlogSpecificationExtensions{publicstaticISpecification<Blog>CreatedAfter(thisISpecification<Blog>specification,DateTimedateTime){returnspecification.And(x=>x.Created>=dateTime);}}

The composed rule can be instantiated like below. The result is thatthe business rules can be read more fluently.

varspecification=SpecificationBuilder<Blog>.Create().CreatedAfter(dateTime).NotBanned().NotExpired();

Building and running

Requirments

dotnet core >= 2.0

This repository provides a console application in additional to an xUnitand a Specflow test project.Please note that Specflow project only worksin Windows environment.

Running

Running the console application:

cd src/SpecificationDemodotnet ef migrations add InitialCreate --startup-project ../SpecificationDemoConsoledotnet ef database update --startup-project ../SpecificationDemoConsoledotnet run

Running tests:

dotnettest SpecificationDemoXunitTestdotnettest SpecificationDemoBddTest

Testing specifications on LinqPad

Requirements:

LinqPad >= 5.26Entity Framework 7 (EF Core) Driver >= 2.0.1

Before configuring the connection, you need to publish one project:

cd src/SpecificationDemoConsoledotnet publish

Then configure the connection following the steps below:

  • Add a new connection
    • Use a typed data context using Entity Framework 2.0.1
    • In thePath to custom assembly, select the publish directory. Example:D:\dotnet-specification-pattern\src\SpecificationDemoConsole\bin\Debug\netcoreapp2.0\SpecificationDemo.dll
    • Select theFull type name of the typed DbContext: SpecificationDemo.Data.BloggingContext
    • SelectVia a constructor that accepts a string:Server=(localdb)\mssqllocaldb;Database=Blog;Trusted_Connection=True;ConnectRetryCount=0
    • SelectRemember this connection

Create a new query and change toC# Program. Then, select theBloggingContext in SpecificationDemo.dll connection.

Inquery properties (F4), add the following namespaces:

SpecificationDemo.DataSpecificationDemo.EntitiesSpecificationDemo.SpecificationsSystemSystem.DataSystem.LinqSystem.Threading.Tasks

LinqPadC# Program sample code :

voidMain(){varblogRepository=newEfReadRepository<Blog>(this);varspecification=SpecificationBuilder<Blog>.Create().NotExpired().CreatedAfter(newDateTime(2017,1,1));varresult=blogRepository.Where(specification, b=>b.Posts).ToList();Console.WriteLine(result);}

UsingC# Statement(s) this can be simplified to:

varspecification=SpecificationBuilder<Blog>.Create().NotExpired().CreatedAfter(newDateTime(2017,1,1));Console.Write(Blogs.Where(specification));

License

Copyright (c) 2018 André Gomes

Licensed under theMIT License.

Releases

No releases published

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp