Archives

Archives / 2009 / April
  • Builder Pattern and Fluent Interface

    In the post I want to discuss the practical part of the Builder pattern and how builder pattern usage and implementation can be simplified by Fluent Interface, it will show how these two patterns can leave in harmony with each other.

    For how many of us happened that requires enum types to be more complex types, to have a description for each enum or other additional fields. In the description field case we can attach attributes description above each enum value and using reflection to obtain them, in some cases it is a handy solution but in other it’s not. Of course each solution has its limitation, and in many cases enum types are not very helpful.

    As another solution, we can create a class with static readonly fields, this could be a typical implementation:

    public class EnumType

    {

        public static readonly EnumType ONE = new EnumType(1, "Descr1");

        public static readonly EnumType TWO = new EnumType(2, "Descr2");

        public static readonly EnumType THREE = new EnumType(3, "Descr3");      

     

        private readonly int id;

        private readonly string description;

     

        private EnumType(int id, string description)

        {

            this.description = description;

            this.id = id;

        }

     

        public int Id

        {

            get { return id; }

        }

     

        public string Description

        {

            get { return description; }

        }

    }

    Here are only Id, and Description fields but of course can be more or less depending on the requirements.

    Of course, using class instead of enums we will lose other facilities one of them is switch structure usage. To solve last issue I will try to apply Builder pattern. Shortly Builder pattern is a design pattern and its focus is on constructing a complex object step by step. Maybe we will not use it in its “GoF form”, but finally the idea of the patterns is that they are not ready to use solution they are adaptable and should be adapted to the context.

    What it will “build” is the switch structure that we can use for class types, similar to above EnumTypes class, but of course our switch usage is not limited only to the type.

    Here is a test that will try to pass further:

    [Test]

    public void CanCreateSimpleSwitchBuilder()

    {

        EnumType state = null;

        var enumType = EnumType.THREE;

        var builder = new SimpleSwitchBuilder();

        builder.Switch(enumType);

        builder.Case(EnumType.ONE);

        builder.Body(() => { Console.WriteLine(EnumType.ONE); state = EnumType.ONE; });

        builder.Case(EnumType.TWO);

        builder.Case(EnumType.THREE);

        builder.Body(() => { Console.WriteLine("->" + EnumType.TWO + EnumType.THREE); state = EnumType.TWO; });

        builder.Default.DefBody(() => Console.WriteLine("Def"));

        builder.Do();

     

        Assert.AreEqual(state, EnumType.TWO);

    }

    I will not show the SimpleSwitchBuilder code for the test which will pass it because usage of the SimpleSwitchBuilder class is ugly. But the idea is simple, Switch method sets state which will be tested against each Case value, then are Case methods which can cascade and a body represents a action that will be executed when Do method is invoked, if there is no Case for the Switch value then is executed Default action if it is specified.

    To increase readability we will introduce fluency for the SimpleSwitchBuilder:

    [Test]

    public void CanCreateSimpleFluentSwitchBuilder()

    {

        EnumType state = null;

        EnumType enumType = EnumType.THREE;

        new SimpleSwitchBuilder()

        .Switch(enumType)

            .Case(EnumType.ONE)

                .Body(() => { Console.WriteLine(EnumType.ONE); state = EnumType.ONE; })

            .Case(EnumType.TWO)

            .Case(EnumType.THREE)

                .Body(() =>

                {

                    Console.WriteLine("->" + EnumType.TWO + EnumType.THREE);

                    state = EnumType.TWO;

                })

            .Default

                .DefBody(() => Console.WriteLine("Def"))

        .Do();

     

        Assert.AreEqual(state, EnumType.TWO);

    }

    The readability is increased making the each method return itself (this), That is how we introduce the fluency.

    Here is the code for the Simple Builder:

    public class SimpleSwitchBuilder

    {

        private Action defaultAction;

        private object testObject;

        private IList<object> caseList;

        private readonly IDictionary<object, Action> caseActions = new Dictionary<object, Action>();

     

        public SimpleSwitchBuilder() { }

     

        public SimpleSwitchBuilder Switch(object obj)

        {

            caseList = new List<object>();

            testObject = obj;

            return this;

        }

     

        public SimpleSwitchBuilder Case(object obj)

        {

            caseList.Add(obj);

            return this;

        }

     

        public SimpleSwitchBuilder Body(Action action)

        {

            foreach (var switchCase in caseList)

            {

                caseActions.Add(switchCase, action);

            }

     

            caseList = new List<object>();

     

            return this;

        }

     

        public SimpleSwitchBuilder Default

        {

            get { return this; }

        }

     

        public SimpleSwitchBuilder DefBody(Action action)

        {

            defaultAction = action;

            return this;

        }

     

        public void Do()

        {

            foreach (KeyValuePair<object, Action> caseAction in caseActions)

            {

                if (ReferenceEquals(caseAction.Key, testObject) || Equals(caseAction.Key, testObject))

                {

                    caseAction.Value();

                    return;

                }

            }

     

            if (defaultAction != null)

                defaultAction();

        }

    }

    Ok, fluency is nice, but what if the switch class is not used correctly, and method invocation order is not correct?

    [Test]

    [ExpectedException(typeof(NullReferenceException))]

    public void CanCreateSimpleSwitchBuilderInWrongWay()

    {

        new SimpleSwitchBuilder()

            .Default

                .DefBody(() => Console.WriteLine("Def"))

            .Case(EnumType.ONE)

                .Body(() => Console.WriteLine(EnumType.ONE))

        .Do();

    }

    The exception will rise, but it will not say anything about the problem, to solve the problem we can introduce validation of the methods call order BUT it could become very complex, the validation will be more complex than implementation itself, and the validation will hide the real switch logic.

    In order to solve the problem we will introduce interfaces, each interface will return its methods for the next switch step:

        public interface IDo

        {

            void Do();

        }

     

        public interface IBody : IDo

        {

            ICase Case(object obj);

            IDefault Default { get; }

        }

     

        public interface ICase

        {

            ICase Case(object obj);

            IBody Body(Action action);

        }

     

        public interface IDefault

        {

            IDo Body(Action action);

        }

     

        public interface ISwitch

        {

            ICase Switch(object obj);

        }

    Implementing the interfaces will allow having following fluency without any complex validation and knowing details of usage of the methods, also the usage is more intuitive.

    Instead of many methods that can lead to wrong usage order (see pervious examples):

    We will have nice and intuitive usage:

    Here is the full source code.

    Conclusion

    Builder pattern and fluent interface pattern in various scenarios can not only simplify and make more intuitive API usages but also simplify its validation logic. There are other ways of implementation of the fluent interface pattern, for example using nested class.

    Thank you,

    Artur Trosin

    Read more...

  • Rhino Tools: Rhino Security Guide

    In the post I want to discuss basics of Rhino Security which was developed by Ayende. This is a nice security model implementation that could be easily integrated and adapted in many applications and scenarios. Intention of the post is to give good startup for Rhino Security. I will try to follow KISS (Keep It Simple) in my explanations, yes, I know that “It's All Relative” :) and also keep to minimum required infrastructure for the startup (mainly only required). Rhino Security is a part of Rhino tools, which is a set of already mature reusable classes and tools that cover various scenarios, such as well known:

    1.Rhino Mocks - mocking framework

    2.Rhino Service bus – enterprise service bus implementation

    3.Rhino Common – set of reusable classes (working with threads, IoC, helpful Http Modules, ect..)

    4.Rhino ETL (Extract Transform Load) – library that allows moving data in various formats.

    5. Rhino Queues - queuing service that queues over the Internet

    6. Rhino DHT - Rhino Persistent Hash Table

    7.And many other goodies.

    Rhino Security in my opinion is less popular then other Rhino stuff, one reason could be that is on web is not so much information. That is why I want to put the basics of Rhino Security and show how easy you can setup working application based on Rhino Security(by “easy” I mean that is much easier to setup rhino security then to try to implement at least a little part of it).

    Rhino Security implementation is not very huge in terms of code lines, but is based on many other set of classes. I will describe them shortly later. Rhino Security as a persistence mechanism uses NHibernate that allows you very easy to integrate with many RDBMS types. To more precise Rhino Security could be configured with both: Castle Active Record and NHibernate. Castle Active Record is Active Record pattern implementation which behind the scene uses NHibernate (mmm,… yes,…it is not only Active Record pattern implementation, it has much more other features than are described by classic Active Record pattern). I’ve chosen to use NHibernate because it is more popular then Castle Active Record (Castle AR) and other reason is that Castle AR can’t be used without NHibernate but NHibernate without Castle AR can :).

    Let’s do first steps and get all the Rhino bits from SVN repository, here is the SVN link:

    https://rhino-tools.svn.sourceforge.net/svnroot/rhino-tools/trunk/

    in order to Check out the repository you can use any of SVN clients, there are many free:

    1)http://tortoisesvn.net/about - easy to use and is integrated in windows explorer

    2)SmartSVN – the SVN client has two versions, free and more limited and professional version, I like the client and I use it in day by day work, and even its free version is powerful enough to handle various scenarios.

    I will not dive deep in “How To checkout” details, so the result of checking out from the trunk is on the next image. On the image is the last trunk at the moment, 2077. Rhino Security is in “security” folder, but we will not touch it now. In the root folder are “readme” files for some additional information. Also in the root folder are various NAnt and bat files that will invoke NAnt and build entire projects tree. In order to build a little bit faster run “build_without_tests.cmd” file. After a black screen and a lot of blinking lines will be generated “build” folder that will contain all the generated assemblies for all Rhino projects and dependencies.

    If you have made all the steps successfully then let’s start and setup first Rhino Security project, if not then all required assemblies and project sample are in attached zip file.

    Rhino Folder Structure

    So, create a new folder where we will set our new project. Then in the root of just created folder create a new folder “libs” where we will place all required assembly references and dependencies.

    Now, copy following 20 assemblies from Rhino’s generated “build” folder to “libs” folder: 

    Rhino Libs

    Then open visual studio and create a new console project, name the project “RhinoSecurity”, and place it in the created root folder (on the same level as “libs” folder).

    Rhino Sample

    In just created project reference following assemblies from our “libs” folder:

    Rhino Sample

    NHibernate.ByteCode.Castle.dll – assembly is not used directly from our code, but we reference it because it is loaded runtime and should be copied to the output bin folder. The assembly contains implementation for three NHibernate interfaces which are used to generate in memory proxy classes for our POCO mapped classes such as User entity which will be discussed further (that is why we need to set mapped properties as virtual). In this case is used Castle but you can find other implementations.

    Now we have a good base to start type our logic. But, before to dive in implementation details, let’s discuss few Rhino Security types that can help us to integrate Rhino Security with our domain model. Most of the systems nowadays have User entity in the domain model, the User entity can have various proprieties that are specific for each different domains. Rhino Security allows attaching the security implementation to any User entity with minimal changes to the existent User entity, but how Rhino Security knows which entity from our model represents the User? For that is responsible Rhino.Security.IUser interface that marks the User entity, the only member of the interface which should be implemented is SecurityInfo member.

    Here is typical implementation of the interface which fits in many common user implementations:

    public class User : IUser

    {

        private long id;

        private string name;

     

        public virtual long Id

        {

            get { return id; }

            set { id = value; }

        }

     

        public virtual string Name

        {

            get { return name; }

            set { name = value; }

        }

     

        /// <summary>

        /// Gets or sets the security info for this user

        /// </summary>

        /// <value>The security info.</value>

        public virtual SecurityInfo SecurityInfo

        {

            get { return new SecurityInfo(name, id); }

        }

    }

    The Id property is usually identity of the User entity (which not necessary should be a long). SecurityInfo property is used by Rhino Security to attach our user entity to Rhino Security implementation which is used internally by the framework to manage authorization logic for the User. [Mapping file for the User entity and NHibernate configuration are in the provided source code sample] Now I’ll try to describe main Rhino Security model entities from my point of view, which we will explore lately in practice:

    -UserGroup – is a user group defined by its name, it’s used to associate users to the group and define common permissions for users that belong to the group. The groups can be structured hierarchically in parent/child relationship. In some cases you can think about users group in terms of Roles which have set of permissions ex: Administrator, Guest, etc…

    - Operation – a named operation that also can be structured hierarchically using following convention: “/Content/View”, “/Content/Edit” etc… so if we create a new “/Content/Edit” operation then are created two operations “/Content” as parent and “/Content/Edit” as child. Further you can allow or deny the operation for a User or for a UserGroup. When an operation is allowed or denied for a User, UserGroup, etc… also could be specified a level, levels defines importance of the permission, but very often is used Default Level which is equal to 1. Permission with higher level is more dominant in taking decision of operation allowance. For example: if we deny operation “/Content/View” with default level for a user and after that allow for the same operation but with level 9 then finally the operation will be allowed for the user.

    -Permission- is result of allow or deny process for an operation (e.g. “/Content/View”) for a User or UserGroup (or EntityGroups).

    -User – represent any entity that implements IUser interface, we already covered it above…

    I didn’t cover here EntityGroups, IEntityInformationExtractor, Query Permissions,.. maybe I will cover them in the next posts because I want to concentrate on the basic and most common things, here I only want to mention that they exists and you can use them to associate permissions for any entity that implements IEntityInformationExtractor interface.

    For a completeness of the entire image I want to show Rhino Security Data Model and to comment it:

    Rhino Security Database Model

    All tables which are prefixed with “security_” are related to directly Rhino Security, Users table is used to persist User entity.

    Again, tables from red region I won’t touch now because they are related to Entities, shortly, the tables from red region are used to associate permission for entities like Accounts from a given EntitiesGroups or to entities directly (omitting EntitiesGroups) that implements IEntityInformationExtractor which are related by SecurityKey (Accounts.SecurityKey with security_EntityReferences.EntitySecurityKey).

    So, from the above diagram we can see that we can allow or deny operations by permission for Users or UserGroups. A User can belong to one or more UserGroups. Operations and UserGroups can be structured hierarchically in parent\child relationship. That’s it... Nothing complicated, is it?

    Back to Code:

    So, let’s initialize Rhino Security on order to make it work.

    First of all we need to initialize Windsor Inversion of Control Container and add at least two Windsor facilities:

    1) NHibernateUnitOfWorkFacility

    2) RhinoSecurityFacility

    we can do it programmatically or using configuration file, here is programmatic version:

    //Create container

    container = new WindsorContainer();

    //Register Unit Of Work Facility instance

    container.Kernel.AddFacility("nh", new NHibernateUnitOfWorkFacility());

    //Regiser Rhino Security Facility instance:

    //1) provide Rhino’s DB table naming convetion:

    //  Prefix '_'              ex: security_Permissions or

    //  Schema '.'(is default). ex: security.Permissions

    //2) provide User Type that implements IUser

    container.Kernel.AddFacility("security",

                                 new RhinoSecurityFacility(SecurityTableStructure.Prefix, typeof (User)));

    All code explanations are in the comments, only what I want to add is that we need to run the code once in application startup.

    The configurations could be setup in few ways, and most of them which I saw were using Rhino Bindsor which is Domain Specific Language written in Boo that allows configuring Castle Windsor Inversion of Control container without using any xml tag. Maybe some of you already noted I didn’t go with Boo way, because it can look as more “exotic” way for some folks.

    Next, we need to resolve Rhino Security repository\services\facades that will allow us to manage and query Rhino Security model:

    //The repository is main "player" that allows to manage security model

    authorizationRepository = IoC.Resolve<IAuthorizationRepository>();

    //The service provides authorization information                      

    authorizationService = IoC.Resolve<IAuthorizationService>();

    //Provide a fluent interface that can be used to assign permissions

    permissionsBuilderService = IoC.Resolve<IPermissionsBuilderService>();

    //Allow to retrieve and remove permissions

    //on users, user groups, entities groups and entities.

    permissionService = IoC.Resolve<IPermissionsService>(); 

    Now, let’s create a transient User entity and save it to DB.

    //Create a User

    var userArt = new User { Name = ("ArturTrosin") };

    UnitOfWork.CurrentSession.Save(userArt);

    The user entity we will use to operate with. Then create two groups, child and parent:

    //Create "AdminUserGroup" UsersGroup                 

    authorizationRepository.CreateUsersGroup("AdminUserGroup");

    //Create Child group for "AdminUserGroup"

    authorizationRepository.CreateChildUserGroupOf("AdminUserGroup", "GuestUserGroup");

    Then create three operations:

    //Create two operations: root /Content          operation

    //              and its child /Content/Manage   operation

    authorizationRepository.CreateOperation("/Content/Manage");

    UnitOfWork.Current.TransactionalFlush();

    //Create third operation as child of the /Content

    authorizationRepository.CreateOperation("/Content/View");

    Associate user with created group:

    //add user to "AdminUserGroup", so all further permissions for "AdminUserGroup"

    //group are aslo applied for the user also              

    authorizationRepository.AssociateUserWith(userArt, "AdminUserGroup");

    Here is how we can associate two permissions for a user group or a user:

    //Create Permission using Builder Pattern

    //and its fluent interface:              

    permissionsBuilderService

      //Allow "/Content" Operation

      .Allow("/Content")

      //for "AdminUserGroup"

      .For("AdminUserGroup")

      //Could be specified On an entityGroup

      //or an entity that implemented IEntityInformationExtractor 

      .OnEverything()

      //Here could be specified Permission priority Level

      //DefaultLevel is equal with 1

      .DefaultLevel()

      .Save();

     

    //Create Deny permission for user with level 5   

    permissionsBuilderService

      .Deny("/Content/View")                 

      .For(userArt)                

      .OnEverything()                 

      .Level(5)

      .Save();

     

    In the next code lines are demonstrated few Rhino Security methods that allows you to retrieve various info:

    //Ask users allowance for an Operation

    bool isAllowedContentOp = authorizationService.IsAllowed(userArt, "/Content");

    bool isAllowedContentManageOp = authorizationService.IsAllowed(userArt, "/Content/Manage");

     

    //Retrieve Rhino Security entities 

    UsersGroup adminUsersGroupWithoutUser = authorizationRepository.GetUsersGroupByName("AdminUserGroup");

    Operation contentViewOp = authorizationRepository.GetOperationByName("/Content/View");

    Permission[] userArtPermission = permissionService.GetPermissionsFor(userArt);

     

    //Retrieve athorization info that can help to

    //understand reason of allowance (or not) of an operation

    //its very helpful for debuging

    AuthorizationInformation authInfo = authorizationService

                                                       .GetAuthorizationInformation(userArt, "/Content");

    And finally remove created entities:

    //Cleanup created entities

    authorizationRepository.RemoveOperation("/Content/Manage");

    authorizationRepository.RemoveOperation("/Content/View");

    authorizationRepository.RemoveOperation("/Content");

    //Remove child group first

    authorizationRepository.RemoveUsersGroup("GuestUserGroup"); 

    authorizationRepository.RemoveUsersGroup("AdminUserGroup");              

     

    authorizationRepository.RemoveUser(userArt);               

    UnitOfWork.CurrentSession.Delete(userArt); 

    Link to full source code and libs is here.

    Note that I didn’t show code of UoW Flush method calls, which persists changes to DB. And of course in order to run the code you need a database with Rhino Security DB schema in it similar to provided earlier, so there is a method which will do all the dirty work for you:

    new DbSchema().Generate(container);

    The only thing that you should care is to create an empty DB (named Security_Test) and verify if connection string from hibernate.cfg.xml file is set properly.

     Conclusion

    Even Rhinos tools could be not compatible between SVN versions; However most of the Rhino bits are used already in production environments and are very popular with a great community support.

    So, I would recommend taking Rhino Security in account if you already use NHibernate and if you need a similar model or your required model could be expressed with Rhino Security model.

    Notice: The code is tested with VS 2008 sp1 and Sql server 2005.

    Thank you,

    Artur Trosin

     

    Read more...