Arch.Aspects

Arch have a set of attributes named "Aspects". They provide AOP functionalities that improve the entities functionalities.

Class aspects

Order

Set a default order of retrieving Entity. It uses the System.Linq.Dynamic extensions with the same API.
You can also specify a boolean to say if you want to execute the order in the database (on the linq database provider) or in the .Net application (with Linq to Object).

Example:

[Order("IsActive desc, Provider.Name, CreationDate desc")]
public class Test
{ 
    public virtual Provider Provider { get; set; }
    public virtual DateTime CreationDate { get; set; }
    public virtual bool IsActive { get; set; }	
}

The repository will return Test entities ordered by the "IsActive" flag (active tests first), then by the name of its provider (another entity) and then by creation date (the newest first).

Includes

Specify the related entities to load at the same time from the Database. Like the EntityFramework API you can chain properties.
This aspect should be only used on n to 1 or 1 to 1 relations for performances reasons.

Example:

[Includes("Provider, CreationUser.Address")]
public class Test
{ 
    public virtual Provider Provider { get; set; }
    public virtual User CreationUser { get; set; }	
}

The repository will load Test entities with the provider, the user, and the user address loaded in one query.

SecurityAccess

Informative aspects used by other Arch# components (and can be use by code in your application). You can specify the global accessibility to operations (None, Authenticated, Any) and specific to roles. If roles are set for an operation, the global accessibility is set to Authenticated.
There is 4 operations: Read, Delete, Create, Update with roles properties (ReadRoles, DeleteRoles, CreateRoles, UpdateRoles) and access properties (ReadAccess, DeleteAccess, UpdateAccess, CreateAccess).
There are also the WriteAccess and WriteRoles properties, shortcuts to set Delete/Create/Update rights with one property.

Example:

[SecurityAccess(ReadAccess = Access.Authentified, WriteRoles = "Admin")]
public class Test { }

The Test entities can be read only to authenticated user and created/updated/deleted only by user with the "Admin" role.

Property aspects

AutoNow

Push the DateTime.Now in the property at each Delete/Update/Create operation.

Example:

public class Test
{ 
    [AutoNow]
    public virtual DateTime UpdateDate { get; set; }
}

AutoNowCreate

Like AutoNow but only at the creation of the entity, useful for "CreationDate" field.

Example:

public class Test
{ 
    [AutoNowCreate]
    public virtual DateTime CreationDate { get; set; }
}

Increment

Increment the value at each Update operation, useful for version tracking.

Example:

public class Test
{ 
    [Increment]
    public virtual int Version { get; set; }
}

Validate

//TODO

Method aspects

AspectBehaviorAttribute

AspectBehaviorAttribute and its derived types (CreatingAttribute, CreatedAttribute, UpdatingAttribute, UpdatedAttribute, DeletingAttribute, DeletedAttribute, LoadingAttribute, LoadedAttribute) are attributes that can be added to entity methods.
They execute the method at a specific moment of the entity lifetime.
There is 2 possibilities to intercept the entities lifetime in Arch#: Use the Aspect Behaviors or create specific Repository. Choose the way you like more.

Example:

public class Test
{
    public virtual int Version { get; set; }
	
    [Creating]
    public void Creating()
    {
	Version = 1;
    }
}

About Interception

Some Arch# aspects are "Interception aspects" (like AutoNow, Creating ...) that can intercept the lifetime of entities and execute specific code.
If you want to create an Interception aspect you just have to create an attribute and implement the IMemberAspectInterceptor interface.

In this interface, you can specify the actions your aspect is targeting with the Targets property and the code execution with the Intercept method.
This method gives you the instance of the current entity and the reflection MemberInfo of the member where the aspect is placed.

Example:

namespace Arch.Aspects
{
    [AttributeUsage(AttributeTargets.Property)]
    public class AutoNow : Attribute, IMemberAspectInterceptor
    {
        public void Intercept(object entity, MemberInfo member)
        {
            ((PropertyInfo) member).GetSetMethod().Invoke(entity, new object[] { DateTime.Now });
        }

        public AutoNow()
        {
            Targets = ActionTarget.Creating | ActionTarget.Updating | ActionTarget.Deleting;
        }

        public virtual ActionTarget Targets { get; protected set; }
    }
}

Last edited Apr 12, 2011 at 10:41 PM by anthyme, version 2

Comments

No comments yet.