Automation deployment process using Powershell and Psake

Setup

git clone https://github.com/jincod/build-scripts.git

Change your solution name in scripts\build-scenario.ps1:

properties {
  $Solution = "$ProjectDir\YourSolution.sln"
}

Usage

Build all:

build.cmd

Only clean:

build.cmd clean

Added tasks

task Tests -depends Init {
  $tests = (Get-ChildItem $OutDir -Recurse -Include *Tests.dll)
  exec { & $nunit /noshadow /framework:"net-4.0" /xml:"$OutDir\Tests.nunit.xml" $tests }
}

Call from build step TeamCity

build-step

Github

https://github.com/jincod/build-scripts

Jincod.CQRS

Interfaces for for develop app using CQRS principle

Installation

Available on NuGet

PM>Install-Package Jincod.CQRS

Query

QueryContext

public class SimpleQueryContext : IQueryContext<SimpleEntity>
{
}

Query

public class SimpleQuery : IQuery<SimpleQueryContext, SimpleEntity>
{
    public SimpleEntity Execute(SimpleQueryContext queryContext)
    {
        return new SimpleEntity {Name = "Simpl1"};
    }
}

QueryProcessor

var queryProcessor = container.Resolve<IQueryProcessor>();
var context = new SimpleQueryContext();
SimpleEntity simpleEntity = queryProcessor.Process<SimpleEntity, SimpleQueryContext>(context);

Commands

Command

public class SimpleCommand : ICommand
{
}

CommandHandler

public class SimpleCommandHandler : ICommandHandler<SimpleCommand>
{
    public void Handle(SimpleCommand command)
    {
        // do something
    }
}

CommandProcessor

var commandProcessor = container.Resolve<ICommandProcessor>();
var simpleCommand = new SimpleCommand();
commandProcessor.Process(simpleCommand);

Source code available on github

Jincod.CQRS

Using ElasticSearch witn NEST client

Using NEST for create mapping and search Products and Categories.

Model for ElasticSearch index:

public class ProductIndex
{
    public string Id { get; set; }
    public string CategoryId { get; set; }
    public Dictionary<string, object> Params { get; set; }
}

Method for create mapping for ProductIndex:

var indexDefinition = new RootObjectMapping
{
    Properties = new Dictionary<PropertyNameMarker, IElasticType>()
};

var paramsProperty = new ObjectMapping
{
    Properties = new Dictionary<PropertyNameMarker, IElasticType>()
};

var numberMapping = new NumberMapping();
var boolMapping = new BooleanMapping();
var stringMapping = new StringMapping
{
    Index = FieldIndexOption.NotAnalyzed
};

IEnumerable<object> properties = GetAllProperties();
foreach (var property in properties)
{
    switch (property.DataType)
    {
        case DataType.Logic:
            paramsProperty.Properties.Add(property.Id, boolMapping);
            break;
        case DataType.Numeric:
            paramsProperty.Properties.Add(property.Id, numberMapping);
            break;
        case DataType.Text:
            paramsProperty.Properties.Add(property.Id, stringMapping);
            break;
    }
}

indexDefinition.Properties.Add(Property.Name<ProductIndex>(p => p.Params), paramsProperty);
indexDefinition.Properties.Add(Property.Name<ProductIndex>(p => p.Id), stringMapping);
indexDefinition.Properties.Add(Property.Name<ProductIndex>(p => p.CategoryId), stringMapping);

_client.Map<ProductIndex>(x => x.InitializeUsing(indexDefinition));

Build FilterContainer:

FilterContainer filterContainer = BuildParamsFilter(filters);

Create search request:

var request = new SearchRequest
{
    Size = 0,
    Aggregations = new Dictionary<string, IAggregationContainer>
    {
        {
            "agg", new AggregationContainer
            {
                Filter = new FilterAggregator
                {
                    Filter = filterContainer
                },
                Aggregations = new Dictionary<string, IAggregationContainer>
                {
                    {
                        "categoryId", new AggregationContainer
                        {
                            Terms = new TermsAggregator
                            {
                                Size = 0,
                                Field =
                                    Property.Path<ProductIndex>(p => p.CategoryId)
                            }
                        }
                    }
                }
            }
        }
    }
};

Execute query and return result category ids:

ISearchResponse<ProductIndex> result = _client.Search<ProductIndex>(request);

SingleBucket filterAgg = result.Aggs.Filter("agg");
if (filterAgg != null)
{
    IEnumerable<string> categoryIds =
        filterAgg.Terms("categoryId").Items
            .Select(item => item.Key)
            .ToList();
    return categoryIds;
}

Source code available on github

Using private connectionString in Web.config

Web.config:

<connectionStrings configSource="connectionStrings.config"/>

connectionStrings.config:

<connectionStrings>
  <add name="Main" connectionString="localhost" />
</connectionStrings>`

.gitignore:

connectionStrings.config

Refactoring Remove method in MongoDb Repository

First method

public void RemoveById(Guid id)
{
  _collection.Remove(Query.EQ("_id", id));
}

Using:

_repository.RemoveById(id);

Disadvantages:

  • Grownup Repository class with RemoveSomething() methods
  • Depends on string constants (“_id”)

Second method

public void RemoveByQuery(IMongoQuery query)
{
  _collection.Remove(query);
}

Using:

_repository.RemoveByQuery(Query.EQ("_id", id));

Disadvantages:

  • Business logic depends on MongoDb Driver Queries (Query.EQ("_id", id))
  • Depends on string constants (“_id”)

Third method

public void Remove<TValue>(Expression<Func<TEntity, TValue>> expression, TValue value)
{
  _collection.Remove(Query<TEntity>.EQ(expression, value));
}

Using:

_repository.Remove(x => x.Id, id);

Disadvantages:

  • Only eqaul condition (Query.EQ)

Advantages:

  • Can use a lambda expression instead of string constants
  • Clear Repository class

Fourth method

public void Remove(Expression<Func<TEntity, bool>> whereExpression)
{
  _collection.Remove(Query<TEntity>.Where(whereExpression));
}

Using:

_repository.Remove(x => x.Id == id);

Advantages:

  • Can use a lambda expression instead of string constants
  • Clear Repository class
  • Can use any lambda expression (x => x.Id == id)