Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added specification classes

  • Loading branch information...
commit bb27f634082e35ccf095a7402172e0691546e178 0 parents
cpaton authored
20 Snippets.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Snippets", "Snippets\Snippets.csproj", "{BD896065-D774-4AD7-A95A-C0F1CFA6B399}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BD896065-D774-4AD7-A95A-C0F1CFA6B399}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BD896065-D774-4AD7-A95A-C0F1CFA6B399}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BD896065-D774-4AD7-A95A-C0F1CFA6B399}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BD896065-D774-4AD7-A95A-C0F1CFA6B399}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
36 Snippets/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Snippets")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Microsoft")]
+[assembly: AssemblyProduct("Snippets")]
+[assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1243ed06-7a51-4d38-b0ca-0e2fe1d262b3")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
59 Snippets/Snippets.csproj
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{BD896065-D774-4AD7-A95A-C0F1CFA6B399}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Snippets</RootNamespace>
+ <AssemblyName>Snippets</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Specification\AndSpecification.cs" />
+ <Compile Include="Specification\ISpecification.cs" />
+ <Compile Include="Specification\NotSpecification.cs" />
+ <Compile Include="Specification\OrSpecification.cs" />
+ <Compile Include="Specification\Specification.cs" />
+ <Compile Include="Specification\SpecificationExample.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
23 Snippets/Specification/AndSpecification.cs
@@ -0,0 +1,23 @@
+namespace Snippets.Specification
+{
+ /// <summary>
+ /// Combines two specifications together so that the rule is satisified if both of the specifications are satisfied
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public class AndSpecification<T> : Specification<T>
+ {
+ private readonly ISpecification<T> _lhs;
+ private readonly ISpecification<T> _rhs;
+
+ public AndSpecification(ISpecification<T> lhs, ISpecification<T> rhs)
+ {
+ _lhs = lhs;
+ _rhs = rhs;
+ }
+
+ public override bool IsSatisfiedBy(T candidate)
+ {
+ return _lhs.IsSatisfiedBy(candidate) && _rhs.IsSatisfiedBy(candidate);
+ }
+ }
+}
16 Snippets/Specification/ISpecification.cs
@@ -0,0 +1,16 @@
+namespace Snippets.Specification
+{
+ /// <summary>
+ /// Represents a rule that can be applied to an object
+ /// </summary>
+ /// <typeparam name="T">Type of object that the rule applies to</typeparam>
+ public interface ISpecification<T>
+ {
+ /// <summary>
+ /// Checks an instance of a business object to see if it satisifies the rule
+ /// </summary>
+ /// <param name="candidate">Object to check against the rule</param>
+ /// <returns>True if the candidate satisfies the rule false otherwise</returns>
+ bool IsSatisfiedBy(T candidate);
+ }
+}
21 Snippets/Specification/NotSpecification.cs
@@ -0,0 +1,21 @@
+namespace Snippets.Specification
+{
+ /// <summary>
+ /// Inverts the conditions that satisfy a given rule
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public class NotSpecification<T> : Specification<T>
+ {
+ private readonly ISpecification<T> _specification;
+
+ public NotSpecification(ISpecification<T> specification)
+ {
+ _specification = specification;
+ }
+
+ public override bool IsSatisfiedBy(T candidate)
+ {
+ return !_specification.IsSatisfiedBy(candidate);
+ }
+ }
+}
23 Snippets/Specification/OrSpecification.cs
@@ -0,0 +1,23 @@
+namespace Snippets.Specification
+{
+ /// <summary>
+ /// Combines two specifications together so that the rule is satisified if either of the specifications is satisfied
+ /// </summary>
+ /// <typeparam name="T"></typeparam>
+ public class OrSpecification<T> : Specification<T>
+ {
+ private readonly ISpecification<T> _lhs;
+ private readonly ISpecification<T> _rhs;
+
+ public OrSpecification(ISpecification<T> lhs, ISpecification<T> rhs)
+ {
+ _lhs = lhs;
+ _rhs = rhs;
+ }
+
+ public override bool IsSatisfiedBy(T candidate)
+ {
+ return _lhs.IsSatisfiedBy(candidate) || _rhs.IsSatisfiedBy(candidate);
+ }
+ }
+}
56 Snippets/Specification/Specification.cs
@@ -0,0 +1,56 @@
+namespace Snippets.Specification
+{
+ /// <summary>
+ /// Base class for business rules
+ /// </summary>
+ /// <typeparam name="T">Type of object that the rule applies to</typeparam>
+ public abstract class Specification<T> : ISpecification<T>
+ {
+ /// <summary>
+ /// Checks an instance of a business object to see if it satisifies the rule
+ /// </summary>
+ /// <param name="candidate">Object to check against the rule</param>
+ /// <returns>True if the candidate satisfies the rule false otherwise</returns>
+ public abstract bool IsSatisfiedBy(T candidate);
+
+ /// <summary>
+ /// Combines this rule with another to create another rule that is only satisisfied if both rules are satisfied
+ /// </summary>
+ /// <param name="other">Rule to combine this rule with</param>
+ /// <returns></returns>
+ public Specification<T> And(ISpecification<T> other)
+ {
+ return new AndSpecification<T>(this, other);
+ }
+
+ public static Specification<T> operator&(Specification<T> lhs, Specification<T> rhs)
+ {
+ return new AndSpecification<T>(lhs, rhs);
+ }
+
+ public static Specification<T> operator |(Specification<T> lhs, Specification<T> rhs)
+ {
+ return new OrSpecification<T>(lhs, rhs);
+ }
+
+ public static Specification<T> operator !(Specification<T> lhs)
+ {
+ return new NotSpecification<T>(lhs);
+ }
+
+ /// <summary>
+ /// Combines this rule with another to create another rule that is satisisfied if either rule is satisfied
+ /// </summary>
+ /// <param name="other">Rule to combine this rule with</param>
+ /// <returns></returns>
+ public Specification<T> Or(ISpecification<T> other)
+ {
+ return new OrSpecification<T>(this, other);
+ }
+
+ public Specification<T> Not()
+ {
+ return new NotSpecification<T>(this);
+ }
+ }
+}
31 Snippets/Specification/SpecificationExample.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Snippets.Specification
+{
+ public class NotNull : Specification<object>
+ {
+ public override bool IsSatisfiedBy(object candidate)
+ {
+ return candidate != null;
+ }
+ }
+
+ public class Null : Specification<object>
+ {
+ public override bool IsSatisfiedBy(object candidate)
+ {
+ return candidate != null;
+ }
+ }
+
+ public class SpecificationExample
+ {
+ public static void Example()
+ {
+ var tautology = new NotNull() & new Null();
+ }
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.