Archive for c#

gitg – Visual Git Client

A few months ago, I decided to move both private and public software projects over to my github account. My experience so far has been great! The github website is neatly organized and delivers the type of feedback you would expect from a desktop application.

While the website really delivers a superb user experience, I did have the desire to find a suitable desktop application for Linux which would allow me to visualize my commits and repository history. After searching through a few desktop clients in the Fedora repositories I settled on gitg.

Gitg is a GitX clone for GNOME/GTK+. It contains a wide variety of tools for visualizing repository history, committing new changes, and documenting existing commits. The software also shows a visual representation of how code branches were merged, and what changes were merged which each commit. It is a great tool for visually seeing how code changes impact your application without the need for a web application like github.

Creating Generic MVC Controllers

Based on my previous posting regarding Generic Repositories, I decided to take this approach a step further and create Generic Controllers. The idea is simple: create a Generic Controller which can handle all of the CRUD operations by default. If we need to override or extend these methods, we can create a controller which inherits from this Generic Controller. We will also need to create a Controller Factory which will first look for a derived class, if it cannot find one, it will automatically instantiate an instance of the Generic Controller and use this instance as the controller.

First we must create a Generic Controller, capable of handling all of the CRUD requests. Below is my implementation.

public class ApplicationController<T> : Controller<T> where T: class
{
        protected ApplicationRepository<T> Repository { get; set; }
        private string[] _strLockedProperties = new string[] {
            "Id",
            "CreatedOn",
            "CreatedBy",
            "ModifiedOn",
            "ModifiedBy"
        };

        protected virtual string[] LockedProperties
        {
            get
            {
                return _strLockedProperties;
            }
        }

        public ApplicationController()
        {
            Repository = new ApplicationRepository<T>();
        }

        public virtual ActionResult Index()
        {
            return View(Repository.GetAll());
        }

        public virtual ActionResult Create()
        {
            return View();
        }

        [HttpPost]
        public virtual ActionResult Create(T record)
        {
            if (ModelState.IsValid)
            {
                Repository.Insert(record);
                Repository.Save();
            }

            return RedirectToAction("Index");
        }

        public virtual ActionResult Details(Guid id)
        {
            return View(Repository.Get(id));
        }

        public virtual ActionResult Edit(Guid id)
        {
            return View(Repository.Get(id));
        }

        [HttpPost]
        public virtual ActionResult Edit(Guid id, T record)
        {
            var properties = typeof(T).GetProperties();
            var fields = new List<string>();
            foreach (var prop in properties)
            {
                if (!LockedProperties.Contains(prop.Name))
                {
                    fields.Add(prop.Name);
                }
            }
            var allowed = fields.ToArray();
            var existing = Repository.Get(id);

            if (TryUpdateModel(existing, allowed))
            {
                Repository.Save();
                return RedirectToAction("Index");
            }

            return View(record);
        }

        public virtual ActionResult Delete(Guid id)
        {
            return View(Repository.Get(id));
        }

        [HttpPost]
        public virtual ActionResult Delete(Guid id, string confirm)
        {
            Repository.Delete(Repository.Get(id));
            Repository.Save();

            return RedirectToAction("Index");
        }

This class will be able to handle all of the default CRUD operations without worrying about the actual data types. Based on the previous posting, even the repositories will be automatically generated.

If you need any special functionality for a controller, simply create a derived class.

public class UserController : ApplicationController<UserAccount>
{
    public override ActionResult Edit(Guid id)
    {
        //Special code here.
    }
}

Now lets wire up our Controller Factory. We need to create a factory which first looks for a strongly typed controller. If it cannot find that strongly typed controller it will automatically instantiate a new Generic Controller and return this instance.

public class ApplicationControllerFactory : IControllerFactory
    {
        private string Namespace
        {
            get
            {
                return this.GetType().Namespace;
            }
        }

        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            if (string.IsNullOrEmpty(controllerName))
                throw new ArgumentNullException("controllerName");

            Type cType = Type.GetType(Namespace + ".Controllers." + controllerName + "Controller");

            if (cType == null)
            {
                cType = Type.GetType(Namespace + ".Library.ApplicationController`1[" + Namespace + ".Models." + controllerName + "]");
            }

            return Activator.CreateInstance(cType) as Controller;
        }

        public void ReleaseController(IController controller)
        {
            if (controller is IDisposable)
                (controller as IDisposable).Dispose();
            else
                controller = null;
        }

        public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
        {
            return System.Web.SessionState.SessionStateBehavior.Default;
        }
    }

Now register the Controller Factory in your Global.asax.cs file.

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    ControllerBuilder.Current.SetControllerFactory(new ApplicationControllerFactory());
}

The effects on development speed of this approach is pretty profound. Essentially you have a Controller and Repository layer which is completely dynamic, powered only by the meta data of the data layer. All that must be done is creating the views, and overriding your controllers and repositories where necessary.

Repository Pattern, Lazy Style

One of the most annoying things when working with MVC is repeating the same code over and over again at each layer. We can try to abstract our classes, but it still only gets us so far, a lot of the code must still be manually typed or templated. I found myself particularly tired of creating repository objects for each of my database tables. Sure, I was inheriting from a generic base class, but a lot of the implementation I couldn’t get away from.

Using Linq2Sql was one of the reasons for my headaches. Types aren’t so easy to get at, and queries cannot be created dynamically at runtime–or could they? Dynamic Linq to the rescue. Microsoft has a seperate library available for download which actually allows you to run dynamic queries at runtime. Once added to your project, the dynamic functions are added through class extensions to the standard Linq classes.

I decided that I would start by creating a generic, templated, repository layer which could be extended if necessary, but would by default contain all of the necessary functions to interact with the model layer.

using System.Linq.Dynamic;

public abstract class Repository<R> where R : class
{
    public virtual DataContext Context { get; protected set; }

    public Repository() { }

    public Repository(DataContext context)
    {
        Context = context;
    }

    public virtual void Insert(R record)
    {
        Context.GetTable<R>().InsertOnSubmit(record);
    }

    public virtual void Delete(R record)
    {
        Context.GetTable<R>().DeleteOnSubmit(record);
    }

    public virtual void Update(R record)
    {
        return;
    }

    public virtual IEnumerable<R> GetAll()
    {
        var records = from r in Context.GetTable<R>()
                        select r;

        return records;
    }

    public virtual void Save()
    {
        Context.SubmitChanges();
    }

    public virtual void Revert(R record)
    {
        Context.Refresh(RefreshMode.OverwriteCurrentValues, record);
    }
}

Then create a class which inherits from your template, and code in all of the functions which are application specific.

public class ApplicationRepository<R> : Repository<R> where R: class
{
    public ApplicationDataContext AppContext
    {
        get
        {
            return AppContext as ApplicationDataContext;
        }
    }

    public ApplicationRepository()
    {
        AppContext = new ApplicationDataContext();
    }

    public virtual R Get(Guid Id)
    {
        var record = (from  r in AppContext.GetTable<R>().Where("Id = @0", Id)
                        select r).Single();

        return record;
    }

    public virtual IEnumerable<R> GetAll(string clause, params object[] args)
    {
        var records = from  r in AppContext.GetTable<R>().Where(clause, args)
                        select r;

        return records;
    }

    public override void Insert(R record)
    {
        var d = record as dynamic;
        d.Id = Guid.NewGuid();
        d.CreatedOn = DateTime.Now;
        d.CreatedBy = "System";

        base.Insert(record);
    }

    public override void Update(R record)
    {
        var d = record as dynamic;
        d.ModifiedOn = DateTime.Now;
        d.ModifiedBy = "System";

        base.Update(record);
    }
}

In my case, I added a narrowing ApplicationDataContext and some additional functionality. One of the key functions is the GetAll(string, param object[]) function. This allows me to essential run any queries against my database using that Dynamic Linq library. All of the functionality that I need from a repository layer will most likely already exist in this implementation. Anything else that is needed can be added later by inheriting from the ApplicationRepository class. This is going to save me a great deal of time.

AutoMapper

AutoMapper is a great, free library available for .NET and accessible through nuget. It allows you to map and copy property data from one class to properties of another class. It does all of this based on naming convention.

Assume that we have the following the two classes:

class first
{
     public string A { get; set; }
     public string B { get; set; }
     public string X { get; set; }
}
class second
{
     public string A { get; set; }
     public string B { get; set; }
     public string Y { get; set; }
}

If we tell AutoMapper to map from an instance of class first to an instance of class second it will automatically copy the data stored in the public properties A and B from the first class into the second class. Properties Y and Z will not match, and therefore not be copied between the two classes. How does it do this? AutoMapper uses type reflection to automatically match the names of properties in the source class to the names of properties in the destination class.

This technique has many applications, and is available to save countless hours of mapping code. This can even be used to map properties of LINQ to SQL or Entity classes to allow for shallow copying of one object to another. Another application is for creating projection classes for use by an outside method.

How does it work? AutoMapper must be configured with knowledge about which classes to match. This must be done once per Application Domain.

Mapper.CreateMap<first, second>();
Mapper.AssertConfigurationIsValid();

For web applications it is suggested that this mapping be done in the Application_Start method of your Global.asax.cs or Global.asax.vb file. This will ensure that the mapping is only run once per domain. Now that we have told AutoMapper how to map, let’s tell AutoMapper to map something.

var fInstance = new first();
fInstance.A = “hello”;
fInstance.B = “world”;
var sInstance = Mapper.Map<first, second>(fInstance);
Console.WriteLine(sInstance.A + ” ” + sInstance.B);

The output of this application would be “hello world”. AutoMapper would copy the properties in first_instance.A and first_instance.B to a brand new instance of the second class.

At this point, if you tried to compile and run the application, you might be wondering why you are getting an exception. AutoMapper is unable to map first.X to first.Y, and therefore throws an exception. You can force AutoMapper to ignore a column when you creating your mapping using a lambda expression.

Mapper.CreateMap<first, second>().Ignore(a => a.X);

When you run the application again, AutoMapper will ignore that column and your output will be as expected. What happens when there are many columns you wish to ignore? Writing a lambda expression for each column would be tedious. Luckily somebody over at stackoverflow has come up with a handy extension method which you can use to ignore all columns which don’t match.

Tumblr API

I’ve been doing a lot of work recently which requires integration of dynamic content, such as blogs, into existing websites. I decided to first try it out on my own website, realizing that it would make updating content a much simpler process.

I am impressed by how easy the Tumblr API is to implement. They basically give you two options for displaying content on your own website. The first method uses javascript to insert your blog’s content into an existing webpage:

<script type=”text/javascript” src=”http://blog.com/js” />

It’s as easy as that. Your existing blog posts will show up directly on the page you inserted this into. That being said, it isn’t going to look very nice without styling the various elements. The Tumblr API assigns css classes to almost every element which is inserted, making the process of styling a breeze.

The second method utilizes Tumblr’s XML based API services to grab content. Every blog’s API can be accessed via the following path: /api/read/. This request will return the contents of your blog formatted as an XML document. This leaves the dirty work of parsing the XML document up to us. An easy way to do this is to parse each element and add it to an existing Literal control on your ASP.NET page:

private void Tumblr()
{
  var wc = new WebClient()
  var xml = wc.DownloadString(“http://blog.com/api/read”);
  var xdoc = new XmlDocument();
  xdoc.LoadXml(xml);

  foreach (var xelem in xdoc.GetElementsByTagName(“post”))
  {
        var xtitle = xelem.GetElementsByTagName(“regular-title”);
        if (xtitle.Count < 1)
               continue;

          string date = xelem.GetAttribute(“date-gmt”);
          string url = xelem.GetAttribute(“url”);
          string title = xtitle[0].InnerText;
          string body = xelem.GetElementsByTagName(
               ”regular-body”)[0].InnerText;
          litTumbler.Text += string.Format(
                “<h4><a href="{0}" target="_blank">” +
                “({1})  {2}</a></h4>” +
                “{3}<br /><br />”,
                url,
                DateTime.Parse(date).ToString(),
                title,
                body);
     }
}

That’s all that you have to do to show some content from your blog. This has been extremely easy for me to add to use. My only concern is the scalability of that API read function. What happens if your blog contains thousands of posts? I’ll worry about that when the time comes.

Compiling LINQ Queries

The performance of LINQ queries can suffer greatly when an application performs the same query multiple times with different parameters. A good example of this situation occurs when your query is inside of a loop as shown below:

foreach (Company company in CompanyList)
{
     var customers = (from c in context.Customers
               where c.CompanyID == company.ID
               select c); 

     Console.WriteLine(customers.Count);
}

Each iteration of the above loop requires that the query be translated into SQL. This process becomes increasingly costly based on the number of iterations and the complexity of the query.

To increase the performance, .NET’s LINQ implementation allows us to preform compiled queries. Compiled queries require the use of a Generic Function whose implementation contains the LINQ query to execute.

private static Func<DBDataContext, Guid, Customer>
     GetCustomers = CompiledQuery.Compile(
     (DBDataContext context, Guid companyID) =>
               from c in context.Customers
               where c.CompanyID== companyID
               select c);

This function will compile the LINQ query only once. Subsequent calls to the function will reuse the existing compiled query. This greatly increases the performance of subsequent queries and avoids excessive recompilation. You can call the procedure using a standard function call:

foreach (Company company in CompanyList)
{
     var customers = GetCustomers(context, company.ID); 

     Console.WriteLine(customers.Count);
}

For more information: http://msdn.microsoft.com/en-us/library/bb399335.aspx

SSIS: UNC Share Authentication

One common request that I receive while creating SSIS packages for customers is to export some data to a Shared Folder without mapping a drive letter to the share. Usually, I must use different credentials to connect to this share. Below is a code snippet which will connect to the specified share using supplied credentials. Both the share and authentication information are stored as SSIS User Variables.

string strServer = Dts.Variables[“ServerName”].Value.ToString();
string strShare = Dts.Variables[“ServerShare”].Value.ToString();
string strUsername = Dts.Variables[“ServerUsername”].Value.ToString();
string strPassword = Dts.Variables[“ServerPassword”].Value.ToString();
Process pNetDelete = new Process();
pNetDelete.StartInfo.CreateNoWindow = true;
pNetDelete.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
pNetDelete.StartInfo.UseShellExecute = false;
pNetDelete.StartInfo.FileName = “net”;
pNetDelete.StartInfo.Arguments = string.Format(“use /DELETE {0}\
{1} /Y”,  strServer, strShare);
pNetDelete.Start();
pNetDelete.WaitForExit();
Process pNetShare = new Process();
pNetShare.StartInfo.CreateNoWindow = true;
pNetShare.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
pNetShare.StartInfo.UseShellExecute = false;
pNetShare.StartInfo.RedirectStandardError = true;
pNetShare.StartInfo.RedirectStandardOutput = true;
pNetShare.StartInfo.FileName = “net”;
pNetShare.StartInfo.Arguments = string.Format(“use \\{0}\{1} /u:"{2}" "{3}"”,
        strServer, strShare, strUsername, strPassword);
pNetShare.Start();
pNetShare.WaitForExit();
string strError = pNetShare.StandardError.ReadToEnd();
if (pNetShare.ExitCode != 0)
{
    bool fireAgain = false;
    Dts.TaskResult = (int)ScriptResults.Failure;
    Dts.Events.FireInformation(999, “Networking Authentication”,
    strError.Replace(Environment.NewLine, ” “), string.Empty, 0, ref fireAgain);
}
else
    Dts.TaskResult = (int)ScriptResults.Success;

Note: Using this method you will have to store the passwords as clear text variables. I would recommend implementing an encryption function to use with this approach.

SSIS: ConnectionManager To SqlConnection

I spent a decent amount of time trying to figure out how to get the DTS ConnectionManager to give me a SQL Connection. I used the following code to grab a SQL Connection from the connection manager:

SqlConnection sConnection = (SqlConnection)Dts.Connections[“MYDB”].AcquireConnection(null);

We pass NULL into the AquireConnection method to specify that we will not be using an existing transaction. Once the SQLConnection is instantiated, it is usually in the OPEN state and does not require you to call the Open() method it.

Easy enough. Just remember to ALWAYS use this method with an ADO.NET connection. Using anything else will result in an error in an InvalidCastException:

Error: System.InvalidCastException: Unable to cast COM object of type ‘System.__ComObject’ to class type ‘System.Data.SqlClient.SqlConnection’.