WCF

Implementing Undo/Redo feature for DbContext of Entity Framework Code-First

Posted on October 11, 2012. Filed under: .Net, C#, Code-First, EF4, Entity Framework, WCF | Tags: , , , , , |


Download Source Code Here: Source Code

I was curious about change tracking and property values of DbContext and  while playing with that I decided to write snapshot manager which would  take snapshot of my each changes by storing entries And this manager also allow me to undo and redo my changes with DbContext.

DbContext will check all the entities of all types when change tracking is enabled and also verify if they have any changes in their data. Automatic Change tracking is enabled by default. Disabling it would not trigger the DbContext update for each change in the entity. Actually it maintains the state of entities. It uses this to determine the changes needed to be pushed to database when SaveChanges() is called.

The Undo and Redo features allow you to easily correct mistakes or based on some scenario, as well as free you to experiment with different routing and data mapping decisions. Undo reverses the last action you performed, and Redo undoes the last Undo action.

So let’s come to point of creating our snapshots of changes. Since DbContext still doesn’t give any event of DbContext.DetectChanges()execution, I have decided to keep my snapshot in my Repository’s CUD( Create , Update , Delete) operations and also allow user to call it explicitly whenever it is needed- Click here to read my Article in Codeproject about this topic.

Advertisements
Read Full Post | Make a Comment ( None so far )

Repository pattern with Entity Framework Code-First in Composable Service End

Posted on October 3, 2012. Filed under: .Net, C#, EF4, Entity Framework, Expression, WCF | Tags: , , , , , , , , |


Download Source Here

Introduction

Some days ago I was thinking to design data access layer in Composable service end and also decide to use Entity Framework Code-First approach since I didn’t tried that yet after it has been released. That’s why I plan some interfaces act as a contract between composable parts. So client can create proxy by Export and Import using MEF. Beside the service contract I plan to do same job by using some interfaces I need to provide that data and wish avoid coupling and dependency and here the following interfaces in service implementation – IUnitOFWork ,IRepository and IContext to separate the logic that retrieves the data and maps it to the entity model from the business logic that acts on the model. Here are following reason I choose to go in Composable environment –

  • Removes the need for a component to locate its dependencies or manage their lifetimes.
  • Allows swapping of implemented dependencies without affecting the component.
  • Facilitates testability by allowing dependencies to be mocked.
  • Increases maintainability by allowing new components to be easily added to the system.

   And Here is some reason for using repository pattern in data access layer in place direct access the database code-

  • Duplicated code
  • A higher potential for programming errors
  • Weak typing of the business data
  • Difficulty in centralizing data-related policies such as caching
  • An inability to easily test the business logic in isolation from external dependencies

Environment

Model 

I have chosen a very small environment where I just have two model of BlogPost and Category and also a Audit Model which represent the audit log generated by the system when any changes has been made in database.

model c

Data Access  

Data Access is going to hold three interfaces as I have mentioned earlier  – IRepository, IUnitOfWork and    IContext  and their implementation with DbContext and DbSet. Here I have DbContext named BlogContext and their Initializer.

data access c

Using the code  

So here we are going define our Composable Service first. To do that we need to extend service behavior and instance provider there. This instance provider will use a InstanceContext extension named ServiceComposer while creating and releasing instance.

 public class ComposingInstanceProvider : IInstanceProvider
    {
        private Type serviceType;
 
        public ComposingInstanceProvider(Type serviceType)
        {
            this.serviceType = serviceType;
        }
 
        public object GetInstance(System.ServiceModel.InstanceContext instanceContext)
        {
            return this.GetInstance(instanceContext, null);
        }
 
        public object GetInstance(System.ServiceModel.InstanceContext instanceContext,
 System.ServiceModel.Channels.Message message)
        {
            // Create composer:
            var composer = new ServiceComposer();
            instanceContext.Extensions.Add(composer);
 
            // Retrieve instance:
            var instance = Activator.CreateInstance(this.serviceType);
 
            // Compose instance:
            composer.Compose(instance);
 
            // Return instance:
            return instance;
        }
 
        public void ReleaseInstance(System.ServiceModel.InstanceContext instanceContext, object instance)
        {
            // Remove composer:
            var composer = instanceContext.Extensions.Find<ServiceComposer>();
            if (composer != null)
                instanceContext.Extensions.Remove(composer);
 
            // Release instance:
            if (instance is IDisposable)
                ((IDisposable)instance).Dispose();
        }
    }   

In  GetInstance method, a composer name ServiceComposer has been created and add as extension of InstanceContext. Lets take deeper look into that extention class and you can see that the composition part of our service reside in this ServiceComposer class. we have used CompositionContainer and register the AggregateCatalog and container itself. Before you can inject dependencies into an object, the types of the dependencies need to be registered with the container. Registering a type typically involves passing the container an interface and a concrete type that implements that interface. There are primarily two means for registering types and objects: through code or through configuration. Here in this solution We will register types or a mapping with the container. At the appropriate time, the container will build an instance of the type you specify.

        void IExtension<InstanceContext>.Attach(InstanceContext owner)
        {
            compositionContainer = new CompositionContainer(Settings.DefaultCatalog);
            compositionContainer.ComposeExportedValue(compositionContainer);
        }
 
        void IExtension<InstanceContext>.Detach(InstanceContext owner)
        {
            if (compositionContainer != null)
            {
                compositionContainer.Dispose();
                compositionContainer = null;
            }
        } 

Service composer c

So after using the above ServiceBehaviour in service implementation, we will get into composable from the client end we can do Export my service like this way :

    [Export]
    public class LogicServiceClient : ClientBase<ILogicService>
    {
        public virtual ILogicService Invoke
        {
            get { return this.Channel; }
        }
    }    

So now lets jump to the implementation of ILogicService and the data access part to create Repository, UnitOfWork and DbContext. In the implementation of service end, we would like to write code for access data with interfaces of these stuff. So we are hoping to code for data access will be look something like this –

        [Import]
        Lazy<IUnitOfWork> _unitOfWork;
 

        public bool SetData( BlogPost post)
        {
            using (var db = _unitOfWork.Value)
            {
                db.EnableAuditLog = false; 
                using (var transaction = db.BeginTransaction())
                {
                    try
                    {
                        IRepository<BlogPost> repository = db.GetRepository<BlogPost>();
                        repository.Add(post);
                        int i = db.Commit();
                        transaction.Commit();
                        return (i > 0);
                    }
                    catch (Exception)
                    {
                        transaction.Rollback();
                        throw;
                    }
                }
            }
            return false;
        }  

We have used Lazy instance creation of UnitOfWork here. So lets define our first interface of IUnitOfWork

    public interface IUnitOfWork: IDisposable 
    {
        bool EnableAuditLog { get; set; }     
        int Commit();
        IRepository<TSet> GetRepository<TSet>() where TSet : class;
        DbTransaction BeginTransaction();
    }   

Here this UnitOfWork is responsible to creating transaction, commit the changes made , switch on/off audit logging and a factory-method for creating repository instances of expected entity. Here is its implementation

    [Export(typeof(IUnitOfWork))]
    public class UnitOfWork : IUnitOfWork
    {
        [Import]
        private Lazy<IContext> _context;
 
        private CompositionContainer _container;
        private DbTransaction _transaction;
        private Dictionary<Type, object> _repositories;
 
        public bool EnableAuditLog
        {
            get{ return _context.Value.IsAuditEnabled; }
            set { _context.Value.IsAuditEnabled = value; }
        }
 
        [ImportingConstructor]
        public UnitOfWork(CompositionContainer container)
        {
            _container = container;
            _repositories = new Dictionary<Type, object>();
 
        }
 
        public IRepository<TSet> GetRepository<TSet>() where TSet : class
        {
            if (_repositories.Keys.Contains(typeof(TSet)))
                return _repositories[typeof(TSet)] as IRepository<TSet>;
 
            var repository =  _container.GetExportedValue<IRepository<TSet>>();
            repository.Context = this._context.Value;
            _repositories.Add(typeof(TSet), repository);
            return repository;
        }
 
        public void Dispose()
        {
            if (null != _transaction)
                _transaction.Dispose();
 
            if (null != _context.Value)
                _context.Value.Dispose();
        }
       
        public int Commit()
        {
           return _context.Value.Commit();
        }
 
        public DbTransaction BeginTransaction()
        {
           _transaction = _context.Value.BeginTransaction();
           return _transaction;
        }
    } 

In UnitOfWork , feature like commit, transaction and audit option are handled by IContext which is generally represent DbContext and we will see it’s implementation later below. GetRepository() method is going to create IRepository of entity-set and keeping those object reference into Dictionary in reason to re-use  if anyone want it later.The UnitOfWork implements the IDisposable interface to dispose and release all the resources of the DbContext instances also with Transection object Database Connection. The Dispose() method will be automatically called because of the using construct. It is called once scope of the UnitOfWork terminates.

Now, lets concentrate into our IRepository interface. Repositories help us with code reusability and improve testability because they implement interfaces that can be mocked using various mocking frameworks. If all you need is CRUD operations for your new repository then besides writing the name of new class and interface you don’t need to write anything else because your domain specific repository will be using composition approach-

Now, lets concentrate into our IRepository interface-

    public interface IRepository<T> 
    {
        IContext Context { get; set; }
        void Add(T entity);
        void Update(T entity);
        void Remove(T entity);
        T FindSingle(Expression<Func<T, bool>> predicate = null,
        params Expression<Func<T, object>>[] includes);
        IQueryable<T> Find(Expression<Func<T, bool>> predicate = null,
        params Expression<Func<T, object>>[] includes);
        IQueryable<T> FindIncluding(params Expression<Func<T, object>>[] includeProperties);
        int Count(Expression<Func<T, bool>> predicate = null);
        bool Exist(Expression<Func<T, bool>> predicate = null);
    }  

All those stuff related to entity-set has been kept here like Create, Update and Delete and Queries.There are two ways that the repository can query business entities. It can submit a query object to the client’s business logic or it can use methods that specify the business criteria. In the latter case, the repository forms the query on the client’s behalf. The repository returns a matching set of entities that satisfy the query. Now look into the Repository

    [Export(typeof(IRepository<>))]
    public class Repository<T> : IRepository<T> where T : class
    {
        public IContext Context
        {
            get;
            set;
        }
 
        public void Add(T entity)
        {
            this.Context.GetEntitySet<T>().Add(entity);
        }
 
        public void Update(T entity)
        {
            this.Context.ChangeState(entity, System.Data.EntityState.Modified);
        }
        
        public T FindSingle(System.Linq.Expressions.Expression<Func<T, bool>> predicate = null,
 params System.Linq.Expressions.Expression<Func<T, object>>[] includes)
        {
            var set = FindIncluding(includes);
            return (predicate == null) ?
                   set.FirstOrDefault() :
                   set.FirstOrDefault(predicate);
        }
 
        public IQueryable<T> Find(System.Linq.Expressions.Expression<Func<T, bool>> predicate = null,
 params System.Linq.Expressions.Expression<Func<T, object>>[] includes)
        {
            var set = FindIncluding(includes);
            return (predicate == null) ? set : set.Where(predicate);
        }
 
        public IQueryable<T> FindIncluding(params System.Linq.Expressions.Expression<Func<T, 
object>>[] includeProperties)
        {
            var set = this.Context.GetEntitySet<T>();
 
            if (includeProperties != null)
            {
                foreach (var include in includeProperties)
                {
                    set.Include(include);
                }
            }
            return set.AsQueryable();
        }
   
        public int Count(System.Linq.Expressions.Expression<Func<T, bool>> predicate = null)
        {
            var set = this.Context.GetEntitySet<T>();
            return (predicate == null) ?
                   set.Count() :
                   set.Count(predicate);
        }
 
        public bool Exist(System.Linq.Expressions.Expression<Func<T, bool>> predicate = null)
        {
            var set = this.Context.GetEntitySet<T>();
            return (predicate == null) ? set.Any() : set.Any(predicate);
        }
 

        public void Remove(T entity)
        {
            this.Context.ChangeState(entity, System.Data.EntityState.Deleted);
        }
    }

you can see that in most of the method, IContext instance is providing the entity-set of type- IDbSet by the flowing method –

 this.Context.GetEntitySet<T>();  

and during Remove and Update it call method to change state of the entry. So here full look of IContext interface-

public interface IContext : IDisposable
    {
        bool IsAuditEnabled { get; set; }
        IDbSet<T> GetEntitySet<T>() where T : class;
        void ChangeState<T>(T entity, EntityState state) where T : class;
        DbTransaction BeginTransaction();
        int Commit();
    }     

Both UnitOfWork and Repository has used this IContext which is originally provide some services of DbContext. To avoid dependency of  DbContext , IContext has been introduced which provide aggregate root in Repository and UnitOfWork. Here is the DbContext implementation:

[Export(typeof(IContext))]
    public class BlogContext : DbContext, IContext
    {
        public BlogContext()
            : base()
        {
            IsAuditEnabled = true;
            ObjectContext.SavingChanges += OnSavingChanges;
        }
 
        public ObjectContext ObjectContext
        {
            get
            {
                return (this as IObjectContextAdapter).ObjectContext;
            }
        }.....................................

Here we have access the ObjectContext and use it get the event before saving changes into the database. I think you can guess it has been used ..yes, right ….it is for generating the audit log based on the changes we have done. I will describe that implementation later . Let see the implemetation of IContext

        #region IContext Implementation
 
        public bool IsAuditEnabled
        {
            get;
            set;
        }
 
        public void ChangeState<T>(T entity, EntityState state) where T : class
        {
            Entry<T>(entity).State = state;
        }
 
        public IDbSet<T> GetEntitySet<T>()
        where T : class
        {
            return Set<T>();
        }
 
        public virtual int Commit()
        {
            if (this.ChangeTracker.Entries().Any(IsChanged))
            {
                return this.SaveChanges();
            }
            return 0;
        }
 
        private static bool IsChanged(DbEntityEntry entity)
        {
            return IsStateEqual(entity, EntityState.Added) ||
                   IsStateEqual(entity, EntityState.Deleted) ||
                   IsStateEqual(entity, EntityState.Modified);
        }
 
        private static bool IsStateEqual(DbEntityEntry entity, EntityState state)
        {
            return (entity.State & state) == state;
        }
 
        public virtual DbTransaction BeginTransaction()
        {
            var connection = (this as IObjectContextAdapter).ObjectContext.Connection;
            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
            }
 
            return connection
                .BeginTransaction(IsolationLevel.ReadCommitted);
        }
        #endregion  

GetEntitySet<T>() and  ChangeState<T>(T entity, EntityState state) is only two methods those currently is used Respository class to provide DbSet and changing state respectively and all others providing support for IUnitOfWork like creating transaction and commit changes into the database.

Now, To generate audit logs into the database through the following method:

      private List<Audit> CreateAuditRecordsForChanges(DbEntityEntry dbEntry)
        {
            List<Audit> result = new List<Audit>();
 
            #region Generate Audit
            //determine audit time
            DateTime auditTime = DateTime.UtcNow;
            
            // Get the Table name by attribute
            TableAttribute tableAttr = dbEntry.Entity.GetType()
.GetCustomAttributes(typeof(TableAttribute), false).SingleOrDefault() as TableAttribute;
            string tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name;
 
            // Find Primiray key.
            string keyName = dbEntry.Entity.GetType().GetProperties().Single(p => 
p.GetCustomAttributes(typeof(KeyAttribute), false).Count() > 0).Name;
 
            if (dbEntry.State == System.Data.EntityState.Added)
            {
                result.Add(new Audit()
                {
                    Id = Guid.NewGuid(),
                    AuditDateInUTC = auditTime,
                    AuditState = AuditState.Added,
                    TableName = tableName,
                    RecordID = dbEntry.CurrentValues.GetValue<object>(keyName).ToString(),  
                    // Again, adjust this if you have a multi-column key
                    NewValue =ToXmlString( dbEntry.CurrentValues.ToObject())
                }
                    );
            }
            else if (dbEntry.State == System.Data.EntityState.Deleted)
            {
                result.Add(new Audit()
                {
                    Id = Guid.NewGuid(),
                    AuditDateInUTC = auditTime,
                    AuditState = AuditState.Deleted,
                    TableName = tableName,
                    RecordID = dbEntry.OriginalValues.GetValue<object>(keyName).ToString(),
                    NewValue = ToXmlString( dbEntry.OriginalValues.ToObject().ToString())
                }
                    );
            }
            else if (dbEntry.State == System.Data.EntityState.Modified)
            {
                foreach (string propertyName in dbEntry.OriginalValues.PropertyNames)
                {
                    if (!object.Equals(dbEntry.OriginalValues.GetValue<object>(propertyName)
, dbEntry.CurrentValues.GetValue<object>(propertyName)))
                    {
                        result.Add(new Audit()
                        {
                            Id = Guid.NewGuid(),
                            AuditDateInUTC = auditTime,
                            AuditState = AuditState.Added,
                            TableName = tableName,
                            RecordID = dbEntry.OriginalValues.GetValue<object>(keyName).ToString(),
                            ColumnName = propertyName,
                            OriginalValue = dbEntry.OriginalValues.GetValue<object>(propertyName) == null ? 
                            null 
                            : dbEntry.OriginalValues.GetValue<object>(propertyName).ToString(),
                            
                            NewValue = dbEntry.CurrentValues.GetValue<object>(propertyName) == null ? 
                            null 
                            : dbEntry.CurrentValues.GetValue<object>(propertyName).ToString()
                        }
                            );
                    }
                }
            }
            return result;
 
            #endregion 
        } 

During audit, DbEntityEntry has been used here. Table attribute on the model-

    [Table("Categories")]
    [DataContract]
    public class Category : BaseModel
    {.............  

has been seen to get table name and key attribute on field-

    [DataContract]
    public class BaseModel
    {
        [Key]
        [DataMember]
        public Guid Id { get; set;   .......... 

has been used to get primary key. If you have multiple primary key, then you need to handle  how to store them into database. Here in this example I assume single primary key for each model.

And From the entry Original and Current values has been used  to generate  audit  logs. Ok that is it. Thanks For reading.

References

Read Full Post | Make a Comment ( 5 so far )

Custom Authentication and Security for Routing Service of WCF 4.0

Posted on September 13, 2012. Filed under: C#, Routing Service, Security, WCF | Tags: , , , , |


I came across to WCF 4 routing features while designing some Central services which will provide various service to all of my client-end service. I like to create a single entry point to communicate all those service and keep them separate because of scalability reason. WCF routing feature seems to me very exciting which support for a configurable routing service that you can use in your WCF solutions. Provides features for content-based routing, protocol bridging, and error handling. But I have faced some issues there while defining their security context.

Archi

Now a days I am building such architecture where ‘Service L’ in customer domain end will provide some services to Client X, Y , Z and so on.. workstations. ‘Service L’ has lots of things to provide its clients (like data from databases etc… etc…).

And the interesting thing is that in some cases it will consume some services from the Provider End which have been distributed in several independent backend services like ‘Service A’, ‘Service B’. Since those services in Provider domain in not available outside, it has a routing service ‘Router service’ that gives all ‘Service L’ Clients to access the backend services and it act like a bridge to consume them. So all ‘Service L’ going to become as a client to Routing service who send request to it over the internet  and it going to route them to appropriate backend service based on filter/policy. 

The security between Service L and Client X/Y/ Z has already been established and I am not going to talk on that part so. I am very much concern about rest of part I have, the security in the routing environment.

This routing part has been developed based on WCF 4.0 routing feature. But I didn’t find any good solution for the security context when forwarding the messages to backend services.

Archi 2

What about Transport Security?!!

WCF routing is based on message level rather than transport layer routing. Therefore, authentication at transport layer cannot be forwarded correctly by the router and there
hasn’t a direct means to make those security assertion flows from client to
backend (bypass the Router Service). HTTPS/SSL like transport layer solution which can be used only for point to point rather than end to end case. So you cannot establish HTTPS/SSL connection across multiple nodes (client, router and server)

Here the routing service like Consumer –> Routing Service –> Backend Service, than I need to make sure that there is transport security enabled between

· Consumer -> Routing Service

· Routing Service -> Backend Service

According to that, the message will be encrypted on transport from the consumer to the routing service. When the message enters the routing service it will be decrypted, when sending the message to the backend service it will be encrypted again on transport and decrypted at the backend service. So the message will be encrypted and decrypted twice in such solution. But Since There is intermediary systems between client and the service; each intermediate point must forward the message over a new SSL connection.

So Transport security is not appropriate when

· you are sending a message directly from your application to a WCF service and the message will not be routed through intermediate systems

· Both the service and the client are located other than an intranet.

So I am going to avoid Transport security in my scenario.

What about Message Security?!!

Message security is transport-independent and therefore can be used with any transport protocol. When you use message based security this is done on the SOAP message (so the encryption takes place on service level instead of transport level) which gives an End-to-End security solution. So the consumer sends an encrypted message (header is not encrypted default) and the Routing Service just routes the encrypted message to the backend service and the backend service decrypts the message. . So message security directly encrypts and signs the message, having intermediaries does not break the security. But Message based security gives you a performance penalty in comparison to Transport Security, because the message becomes way larger after encrypting it.

So message security with Windows credentials in Router and backend service will work since support of delegation (Kerberos). And Client needs the access to that identity object. On the other hand, it doesn’t also allow me to forward security context for:

· Username and Password

· X.509

· Federated credentials

It means that the router can be configured to enforce message security but the service must be configured to disable security and it cannot access the security context such as the user’s Identity.

So, What I am going to Do

  1. Add extension of endpoint behavior to add headers to send User name and password (Can be send in encrypted way too).
  2. Create a custom binding to encrypt and compression message in between Client and Routing Service.
  3. Use Regular security in binding while forwarding message to back-end service from Routing service.  
  4. Create an authentication manager to do authentication by user name and password (against database) to avoid anonymous calls.

Check out the implementation and full article in Codeproject

Read Full Post | Make a Comment ( None so far )

Liked it here?
Why not try sites on the blogroll...

%d bloggers like this: