Repository and Interface Re-use between Databases

16. August 2010

When using Entity Framework you run into the problem of having either one repository object for each database or having to not use an Inversion of Control due to having to new the Entities Context each time. I have found that this hit on the architecture side is not required.

This is a follow up to the POCO and Context separation post here. It uses that separation to avoid circular references.

Lets start with our Generic Repository and Interface.

public class EntityFrameworkRepository : IRepository
    {
        private ObjectContext _entities;

        public EntityFrameworkRepository(ObjectContext context)
        {
            _entities = context;
        }

        public IQueryable<T> FindAll<T>() where T : class
        {
            return _entities.CreateObjectSet<T>();
        }

        public IQueryable<T> Find<T>(Expression<Func<T, bool>> where) where T : class
        {
            return _entities.CreateObjectSet<T>().Where(where);
        }

        public T Single<T>(Expression<Func<T, bool>> where) where T : class
        {
            return _entities.CreateObjectSet<T>().Where(where).Single();
        }

        public T SingleOrDefault<T>(Expression<Func<T, bool>> where) where T : class
        {
            return _entities.CreateObjectSet<T>().Where(where).SingleOrDefault();
        }

        public T First<T>(Expression<Func<T, bool>> where) where T : class
        {
            return _entities.CreateObjectSet<T>().Where(where).First();
        }

        public T FirstOrDefault<T>(Expression<Func<T, bool>> where) where T : class
        {
            return _entities.CreateObjectSet<T>().Where(where).FirstOrDefault();
        }

        public T Add<T>(T entity) where T : class
        {
            _entities.CreateObjectSet<T>().AddObject(entity);
            _entities.SaveChanges();
            return entity;
        }

        public void Delete<T>(T entity) where T : class
        {
            _entities.DeleteObject(entity);
            _entities.SaveChanges();
        }

        public T Attach<T>(T entity) where T : class
        {
            _entities.AttachTo(entity.GetType().ToString(),entity);
            _entities.SaveChanges();
            return entity;
        }

        public int SaveChanges()
        {
            return _entities.SaveChanges();
        }
    }
public interface IRepository
    {
        IQueryable<T> FindAll<T>() where T : class;
        IQueryable<T> Find<T>(Expression<Func<T,bool>> where) where T : class;
        T Single<T>(Expression<Func<T, bool>> where) where T : class;
        T SingleOrDefault<T>(Expression<Func<T, bool>> where) where T : class;
        T First<T>(Expression<Func<T, bool>> where) where T : class;
        T FirstOrDefault<T>(Expression<Func<T, bool>> where) where T : class;
        T Add<T>(T entity) where T : class;
        void Delete<T>(T entity) where T : class;
        T Attach<T>(T entity) where T : class;
        int SaveChanges();
    }

Notice that we pass in the Object Context. This is what enables us to separate the usage from the declaration. I am going to use Structure Map as it is my preferred IoC but most IoCs implement this functionality.

image

This is in the configuration code block for Structure Map. Notice that the ObjectContext is created to a named instance of the IRepository. The application services are created with the database that they hit. This allows you two things.

1. Re-use of the interfaces and repository objects between databases.

2. Changing the database for a service is now just an IoC Configuration Change.

Enjoy.

Separating POCO and Context in EF 4.0

16. August 2010

I found that I like the streamlined process of working with Entity Framework. The auto generation of domain class is nice when dealing with Existing databases. I dislike having to put domain classes in Infrastructure or putting data base context in Core.

Using the POCO Entities T4 templates you can separate these.

Download here

Add a new Entity Data Model and Generate from the data base.

image

Then right click the background of the model and add a generated code item.

image

Select the POCO Objects

image 

This will create Two .tt files. One is the POCO Classes and one is the Context. We are going to use the onion architecture for this example. We want to move the context to infrastructure so that our model and POCO classes and model are in core.

image

and

image

To separate the context from the Domain we will need to edit the context template. You do not want to edit the classes generated because this will just get wiped out.

image

image

The edit we have to make is to simply add the namespace of the Domain objects to the using statements, and the path of the EDMX file to the input. I am still hunting a way to keep from hard coding a absolute path to the EDMX but until then this will have to work.

 

Enjoy.

Geek Handbook

11. August 2010

I just got done reading “Being Geek”. It is awesome. I would recommend it to any geek that it is the business of IT.

Product: Being Geek by O'Reilly Media

Awesome Handbook

Pros:

Easy to understand, Accurate, Enjoyable, Concise, Well-written

Best Uses:

Novice, Expert, Student, Intermediate

Describe Yourself:

Designer, Educator, Developer, Maker, Sys Admin

This is going to be a book that I have dog-eared, worn-covered, and close at hand. The interview personality section and the offer negotiation sections were incredibly helpful. The conversational style of the writing makes it a very easy read. I found that I was enjoying reading it and laughing and things like the bridge game. I got this book for writing another review and I have to say that it is an awesome find.

jQuery Cookbook

3. August 2010

jQuery Cookbook by O'Reilly Media

Pro. Dev take on the book

by Devlin Liles from Springdale, AR on 8/3/2010

Pros:

Well Organized, Well-written, Concise, Accurate, Helpful examples, Easy to understand

Best Uses:

Expert, Intermediate

Describe Yourself:

Developer

I have been a professional developer for 4 years now mainly focused in the windows services and back ground communication pipelines. I was asked to pick up support for an app written with a lot of jQuery. I was given "jQuery Cookbook" by a friend and I fell in love. It is straight into the meat. Normally I have to wait 2-4 chapters before the useful stuff gets going and with the cookbook I was diving in right away. I haven't written any jQuery before reading the book but I did understand javascript and the DOM. With that foreknowledge the book made jQuery so amazingly easy. I could not have picked up jQuery in 2 short weeks without this book. I recommend this book to any professional developer that is looking to add jQuery to their skill set.

Turning Off Code Block Highlighting in Visual Studio 2010

1. June 2010

I have been using Visual Studio 2010 for a while now and one of the features that drove me crazy was the block highlighting. I went hunting for a way to turn this off. I found it on a MSDN blog post. I have found I like the feature though just no the default colors. Here is the fix I put in place.

Go to Tools –> Options –> Fonts and Colors:

image

In the Display Items list find Collapsible Region Item:

image

Leave the foreground color the default and change the background to a dark gray. I did it with the custom color selector like so.

image

This makes the regions far more eye candy and less ouch.

image

Enjoy.

Converting NUnit Tests to MSTest for CI builds

15. March 2010

So I found a problem that the project I am working on had a bunch of nUnit tests that needed converted to MSTest and I really didn’t want to do a find replace on all the keywords so I did the following.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using TestFixture = Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute;
using Test = Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute;
using TearDown = Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute;
using SetUp = Microsoft.VisualStudio.TestTools.UnitTesting.TestInitializeAttribute;
using TestFixtureTearDown = Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute;
using TestFixtureSetUp = Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitializeAttribute;
using Explicit = Microsoft.VisualStudio.TestTools.UnitTesting.IgnoreAttribute;

Then you just paste this into the using of your test file, and remove your nUnit references. Bob’s your uncle converted.

Productivity, Testing , ,

Visual Studio 2010 Install fest

3. March 2010

The Tyson internal user group and the North West Arkansas User Group are throwing a party. Visual Studio 2010 is here and we need to install it. Bring yourself, your laptop (optional) and come game and install with us. We are have pizza and drinks and a good time.

GDH Has Agreed to sponsor the food!!! Go GDH!

sponsor-gdh 

 logoTysonLogo image mslogo_black

VS2010Installfest

Directions:

Here is the Bing Map

Please register at http://vs2010installfest.eventbrite.com/

Look Forward to seeing you there.

campus Map

Community

Resharper ? Optimize your code analysis

3. March 2010

When running Resharper against legacy code I have found that I would like to turn off code analysis for certain files, folders, or code blocks so I went hunting in Resharper options land and found the nugget that I was hunting for.

Open Resharper Options:

image

Then go to Code Inspection Settings ?>

image

If you add a Generated Code Region Resharper will ignore everything in that region. You can name it something subtle like ?Resharper Ignore this please? like so.

image

You also have that advanced button that allows you to add entire files and folders to be skipped.

image

 

Enjoy the increased performance of Resharper with all your legacy code.

Resharper and Using Directive clean up

3. March 2010

I have come across something in the project that I am working on that is weird. Resharper marks a using directive as unused because we use it through reflection. When we do a clean up it is removed. So I went hunting and found that you can tell Resharper to never removed certain namespaces. You can also tell it to add certain namespaces by default.

Open your Resharper Options Menu.

image

Then go to language ?> Namespace Import

image

Just click add on the should not be removed for the ones you don?t want deleted and add on the right for the ones that you want to add by default.

 

Enjoy.

WCF Serialization of Cyclic References

2. March 2010

When serializing object to a client through WCF you often have reference objects that are needing to be serialized. This becomes a problem if the 
reference parent and reference child are both of the same type. This causes
WCF to barf over cyclic references. There are two fixes. If you are using
.NET 3.5 or previous you can do this (Thanks to Chabster):

namespace MetroServer.Infrastructure
{
    [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Method)]
    public class CyclicReferencesAwareAttribute : Attribute, IContractBehavior,                                                  IOperationBehavior
    {
        private readonly bool _on;

        public CyclicReferencesAwareAttribute(bool on)
        {
            _on = on;
        }

        public bool On
        {
            get { return (_on); }
        }

        #region IOperationBehavior Members

        void IOperationBehavior.AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        void IOperationBehavior.ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
        {
            CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehavior(operationDescription, On);
        }

        void IOperationBehavior.ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
        {
            CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehavior(operationDescription, On);
        }

        void IOperationBehavior.Validate(OperationDescription operationDescription)
        {
        }

        #endregion

        #region IContractBehavior Members

        void IContractBehavior.AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        void IContractBehavior.ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
        {
            CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehaviors(contractDescription, On);
        }

        void IContractBehavior.ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
        {
            CyclicReferencesAwareContractBehavior.ReplaceDataContractSerializerOperationBehaviors(contractDescription, On);
        }

        void IContractBehavior.Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
        }

        #endregion
    }

    public class CyclicReferencesAwareContractBehavior : IContractBehavior
    {
        private const Int32 maxItemsInObjectGraph = 0xFFFF;
        private const bool ignoreExtensionDataObject = false;

        private bool _on;

        public CyclicReferencesAwareContractBehavior(bool on)
        {
            _on = on;
        }

        #region IContractBehavior Members

        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
        {
            ReplaceDataContractSerializerOperationBehaviors(contractDescription, _on);
        }

        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
        {
            ReplaceDataContractSerializerOperationBehaviors(contractDescription, _on);
        }

        internal static void ReplaceDataContractSerializerOperationBehaviors(ContractDescription contractDescription, bool on)
        {
            foreach (var operation in contractDescription.Operations)
            {
                ReplaceDataContractSerializerOperationBehavior(operation, on);
            }
        }

        internal static void ReplaceDataContractSerializerOperationBehavior(OperationDescription operation, bool on)
        {
            if (operation.Behaviors.Remove(typeof(DataContractSerializerOperationBehavior)) || operation.Behaviors.Remove(typeof(ApplyCyclicDataContractSerializerOperationBehavior)))
            {
                operation.Behaviors.Add(new ApplyCyclicDataContractSerializerOperationBehavior(operation, maxItemsInObjectGraph, ignoreExtensionDataObject, on));
            }
        }

        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
        {
        }

        #endregion
    }

    internal class ApplyCyclicDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
    {
        private readonly Int32 _maxItemsInObjectGraph;
        private readonly bool _ignoreExtensionDataObject;
        private readonly bool _preserveObjectReferences;

        public ApplyCyclicDataContractSerializerOperationBehavior(OperationDescription operationDescription, Int32 maxItemsInObjectGraph, bool ignoreExtensionDataObject, bool preserveObjectReferences)
            : base(operationDescription)
        {
            _maxItemsInObjectGraph = maxItemsInObjectGraph;
            _ignoreExtensionDataObject = ignoreExtensionDataObject;
            _preserveObjectReferences = preserveObjectReferences;
        }

        public override XmlObjectSerializer CreateSerializer(Type type, String name, String ns, IList<Type> knownTypes)
        {
            return (new DataContractSerializer(type, name, ns, knownTypes, _maxItemsInObjectGraph, _ignoreExtensionDataObject, _preserveObjectReferences, null /*dataContractSurrogate*/));
        }

        public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
        {
            return (new DataContractSerializer(type, name, ns, knownTypes, _maxItemsInObjectGraph, _ignoreExtensionDataObject, _preserveObjectReferences, null /*dataContractSurrogate*/));
        }

    }

Usage:

[OperationContract]
[CyclicReferenceAware(true)]
Object MyMethod(int number); 

Or if you use .NET 3.5 SP1 you can do this:

[DataContract(IsReference = true)]
public class MyClass
  {
        [DataMember]
        public string MyProperty{ get; set;}
  }

I think you will agree .NET 3.5 SP1 is better.