Friday, September 7, 2012

Sending email from C# code using the GMail SMTP server

Here's how you send email through your Gmail account using C#.

using System;
using System.Net.Mail;
public static class EmailUtility
{
public static void SendEmail(string from, string[] to, string[] cc, string subject, string body, bool isHTML)
{
MailMessage message = new MailMessage
{
Subject = subject,
Body = body,
IsBodyHtml = isHTML,
From = new MailAddress(from),
};
Array.ForEach(to, c => message.To.Add(c));
Array.ForEach(cc, c => message.CC.Add(c));
SmtpClient SmtpMailer = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
Timeout = 50000,
EnableSsl = true
};
SmtpMailer.Credentials = new System.Net.NetworkCredential("youremail@gmail.com", "yourgmailpassword");
SmtpMailer.Send(message);
}
}
view raw EmailUtility.cs hosted with ❤ by GitHub

Wednesday, September 5, 2012

Utility to perform a parameterized SQL Query using ADO.NET

Here's a quick utility method to perform an ADO.NET SQL query. The main tricks are the use of a regular expression to parse out the parameters and the use of a queue to conveniently get the next parameter.

using System.Data.SqlClient;
using System.Text.RegularExpressions;
using System.Collections;
public static class SqlUtility
{
public static T ExecuteScalar<T>(string connStr, string query, params object[] queryParams)
{
using (var con = new SqlConnection(connStr))
using (var cmd = new SqlCommand(query, con))
{
var queue = new Queue(queryParams);
var matches = Regex.Matches(query, @"@\w+");
foreach (Match match in matches)
cmd.Parameters.AddWithValue(match.Value, queue.Dequeue());
con.Open();
T result = (T)cmd.ExecuteScalar();
return result;
}
}
}
view raw SqlUtility.cs hosted with ❤ by GitHub

Tuesday, August 28, 2012

Deep copy of C# object properties

Sometimes you have two different class types with the same properties and you want to copy all the property values from one to the other.

One way is to simply hand code one assignment statement for each field they have in common.

Another option is to use an open source mapping library like AutoMapper

Still other times you might find yourself in the middle ground of not wanting to hand code all the assignments and also not wanting to deal with a 3rd party library.

Here is an example of how you can roll your own automapper in a few lines of code.  This snippet copies like-named properties from a source to a target.  It recurses on any properies that don't have a type starting with "System." and it ignores source properties with value of null.

static void CopyProperties(object sourceObject, object targetObject, bool deepCopy = true)
{
if (sourceObject != null && targetObject != null)
{
(from sourceProperty in sourceObject.GetType().GetProperties().AsEnumerable()
from targetProperty in targetObject.GetType().GetProperties().AsEnumerable()
where sourceProperty.Name.ToUpper() == targetProperty.Name.ToUpper()
let sourceValue = sourceProperty.GetValue(sourceObject, null)
where sourceValue != null
select CopyProperty(targetProperty, targetObject, sourceValue, deepCopy))
.ToList()
.ForEach(c => c());
}
}
static Action CopyProperty(PropertyInfo propertyInfo, object targetObject, object sourceValue, bool deepCopy)
{
if (!deepCopy || sourceValue.GetType().FullName.StartsWith("System."))
return () => propertyInfo.SetValue(targetObject, sourceValue, null);
else
return () => CopyProperties(sourceValue, propertyInfo.GetValue(targetObject, null));
}

Friday, August 24, 2012

RadioButton panel based on an enum type in a C# WinForms application


public class RadioButtonPanel<T> : FlowLayoutPanel
{
public RadioButtonPanel()
{
var graphics = this.CreateGraphics();
var zeroPadding = new Padding(0);
var initialPadding = new Padding(10, 0, 0, 0);
int radioButtonCircleWidth = 30;
graphics.MeasureString("a", RadioButton.DefaultFont);
bool first = true;
foreach (object value in Enum.GetValues(typeof(T)))
{
string name = Enum.GetName(typeof(T), value);
var button = new RadioButton
{
Text = name,
Checked = first,
Padding = zeroPadding,
Margin = first ? initialPadding : zeroPadding,
Width = (int)graphics.MeasureString(name, RadioButton.DefaultFont).Width + radioButtonCircleWidth
};
first = false;
button.CheckedChanged += (s, e) =>
{
if (button.Checked && this.Selected != null)
{
T current = (T)Enum.Parse(typeof(T), name);
this.Current = current;
Selected(current);
}
};
this.Controls.Add(button);
}
this.Current = (T)(object)0;
this.Padding = zeroPadding;
this.Margin = zeroPadding;
}
public event SelectedEvent Selected;
public delegate void SelectedEvent(T t);
public T Current { get; set; }
}

Friday, August 17, 2012

How do mixins work in C#?

Extension methods which target a common marker interface can be viewed as partial implementations of that interface.

If you place such extension methods in different namespaces then it is possible to utilize a technique of "Mixing In" the implementations used by a class.

This is demonstrated in code below.  The one part of this that I took a minute to get my head around was that ILogger loses the semantics of an interface.  The methods available to it are those extension methods which are visible to the compiler as dictated by the using statements.

Some links I learned from before writing this:
namespace MixinDemo
{
public interface ILogger
{
}
}
view raw ILogger.cs hosted with ❤ by GitHub
using System;
namespace MixinDemo.Logger1.Log
{
public static class Mixin
{
public static void Log(this ILogger logger, string message)
{
Console.WriteLine("Logger1 Log: " + message);
}
}
}
view raw Log.cs hosted with ❤ by GitHub
using System;
namespace MixinDemo.Logger2.LogError
{
public static class Mixin
{
public static void LogError(this ILogger logger, string message)
{
Console.WriteLine("Logger2 LogError: " + message);
}
}
}
view raw LogError.cs hosted with ❤ by GitHub
using System;
namespace MixinDemo
{
// Mix in the ILogger functionality required by the implementation of the Program class
using Logger1.Log;
using Logger2.LogError;
class Program
{
ILogger logger = null; // OK to leave uninitialized since only extension methods will be called
static void Main(string[] args)
{
new Program().Execute();
}
private void Execute()
{
try
{
logger.Log("Hello World");
(null as object).GetType(); // error
}
catch (Exception ex)
{
logger.LogError(ex.Message);
}
}
}
}
view raw Program.cs hosted with ❤ by GitHub

Thursday, July 12, 2012

What are extension methods in C#?

Here's a really basic example.


An extension method in C# is a static method defined in a static class with the this keyword placed in front of the first parameter.
public static MyStaticClass {
   public static void DescribeYourself(this int value)
   {
       System.Console.WriteLine("I am an integer with value " + value);
   }
}

public static void Main() {
   int i = 5;
   i.DescribeYourself();
}

Output:
I am an integer with value 5

Do you see what's going on here?  The keyword this causes that static method to effectively behave as though you added an instance method to the int class.

 

Now let's look at a real world example.

Database frameworks often generate code from a data model.  The code follows the pattern of a  container class with properties that expose sets of entitity classes which have properties exposing data.

The container is the gateway to the database and sets of entities to tables with their elements to rows and properties to columns.

For example:

public class Container {
    public Set<Entity> Entities { get; set; }
}

public class Entity {
   public int Id { get; set; }
   public string Name { get; set; }
}

A typical usage of the above would be:
var db = new Container();
var query = db.Entities.Where(c => c.Name == "Foo");
Console.WriteLine("The entity named Foo has Id = " + query.Single());

What if we want something that was a bit more graceful?

Something like:

var db = new Container();
var query = db.Entities.QueryByName("Foo");
Console.WriteLine("The entity named Foo has Id = " + query.Single());

The logical answer starts with, "We have to add a method to the class which defines the type of db.Entities."

Looking to the Container class we see the type of Entities is Set<Entity>.  Can we add a method to that type?  No we cannot (to this point I'm 99% sure but please correct me if I'm wrong here).

Here is where an extension method can give us what we want.

public static class EntityExtensions {
   public static IQueryable<Entity>(
                   this Set<Entity> entities, 
                   string name) {
          return entities.Where(c => c.Name == "Foo");
   }
}

See how we got around that fact that we couldn't add a method to the type Set<Entity>?  The net effect as as if we did though.  It's quite cool.

Thursday, June 28, 2012

Quick way to display a grid of information in a WinForms application.

This C# snippet can be used in a WinForms application to quickly display a grid of information.

Note how the column names are defined using LINQ to Objects.
if (EomAppCommon.Settings.DebugEomDatabase)
{
var form = new System.Windows.Forms.Form();
var grid = new System.Windows.Forms.DataGridView {
AutoGenerateColumns = true,
Dock = System.Windows.Forms.DockStyle.Fill,
DataSource =
(from c in new [] {
Tuple.Create("DADatabaseR1ConnectionString", this.DADatabaseR1ConnectionString),
Tuple.Create("StatsYear", this.StatsYear.ToString()),
Tuple.Create("StatsMonth", this.StatsMonth.ToString()),
Tuple.Create("StatsDaysInMonth", this.StatsDaysInMonth.ToString()),
Tuple.Create("PubReportSubjectLine", this.PubReportSubjectLine),
} select new {
Key = c.Item1,
Value = c.Item2,
}).ToList(),
AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill,
};
form.Controls.AddRange(new[] { grid, });
form.ShowDialog();
}
view raw gistfile1.cs hosted with ❤ by GitHub

Friday, May 18, 2012

How to write a generic extension for ObjectSet<T> that works with entity types having common property names.

Sometimes you have the same properties in multiple entities.

It is possible to end up duplicating the same logic in the manner of the dreaded copy-modify monster.  I have learned to take it seriously when I find myself doing this because it has never not eventually come back to haunt me .

The key to making this work is to first deploy a couple of simple extension methods to make reflection a bit easier.

Then it is less daunting of a task to write a generic routine that acts on any entity set with common propertie(s).

public static class ObjectSetExtensions
{
public static int IdByName<T>(this ObjectSet<T> set, string name) where T : class
{
int id = set.ToList()
.Where(c => c.MemberValue<string>("name") == name)
.Select(c => c.MemberValue<int>("id"))
.FirstOrDefault();
if (id != default(int))
{
return id;
}
else
{
throw new Exception(string.Format("The {0} named {0} does not exist.", typeof(T).Name, name));
}
}
}

Sunday, May 6, 2012

Minimal Code to Demonstrate Entity Framework Code First

Before compiling this, to ensure your project has a reference to a version of Entity Framework that supports code first development, execute the following nuget command:

install-package EntityFramework

The following code listing contains:
  • POCO
  • Context
  • Static method to add an item
  • Application configuration (XML)
  • Unit test (not required)

using System;
using System.Data.Entity;
namespace EFCodeFirst
{
public class Thing
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Model : DbContext
{
public DbSet<Thing> Things { get; set; }
}
public class AddThing
{
public static void Main()
{
var thing = new Thing { Name = @"Something" };
using (var model = new Model())
{
model.Things.Add(thing);
model.SaveChanges();
}
Console.WriteLine("saved changes");
Console.ReadLine();
}
}
}
view raw AddThing.cs hosted with ❤ by GitHub
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<entityFramework>
<defaultConnectionFactory
type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter
value="Data Source=.\SQLEXPRESS; Integrated Security=True; MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
</configuration>
view raw App.config hosted with ❤ by GitHub
using System.Data.SqlClient;
namespace EFCodeFirst.Test
{
public class AddThingTest
{
public void MainTest()
{
AddThing.Main();
int? rowCount = null;
using (var connection = new SqlConnection(@"Data Source=.\musicdb; Integrated Security=True;"))
using (var command = new SqlCommand("select count(*) from [EFCodeFirst.Model].dbo.Things", connection))
{
connection.Open();
try
{
rowCount = command.ExecuteScalar() as int?;
}
finally
{
connection.Close();
}
}
Assert.IsNotNull(rowCount);
Assert.IsTrue(rowCount > 0);
}
}
}
view raw Test.cs hosted with ❤ by GitHub

Friday, May 4, 2012

PowerShell script to delete files from a directory that are more than a given number of days old.

This PowerShell
  • deletes files created more than 3 days ago.
  • logs the files it deletes.
$d = "C:\db\backup"
$today = get-date -uformat "%Y_%m_%d"
$log = "C:\db\backup\" + "Purge_" + $today + ".log"
$a = Get-ChildItem $d -recurse
foreach($x in $a)
{
$y = ((Get-Date) - $x.CreationTime).Days
if ($y -gt 3 -and $x.PsISContainer -ne $True)
{
$deleted = "Deleting - " + $x.fullname + " - Last Write Time - " + $x.LastWriteTime
add-content $log -value $deleted
$x.Delete()
}
}
view raw gistfile1.txt hosted with ❤ by GitHub

Monday, April 16, 2012

How to setup email in Sharepoint 2010 on a Windows 2008 R2 Server (relay to gmail)

  • Use Server Manager to add SMTP server feature
  • Launch IIS 6.0 admin console
  • SMTP Server Properties
    • Allow relay
    • TLS for Delivery
    • Port 587
    • smtp.gmail.com as "smart host"
    • your domain as FDQN
    • Basic authentication with gmail address as user name and its associated password
  • Use Sharepoint Central Adminstration to set the SMTP server

Friday, April 13, 2012

What's a Thread?

One of the challenges for beginner programmers is adapting to the vocabulary in their field. 

The first time I heard the term "multi threaded" I had absoolutely no clue.  Looking up the definition didn't help much either.  At the time, I simply couldn't get over the feeling of being out of my depth.

Although it was a number of years ago, I suppose the same thing happens to beginning computer programmers.  I bet a good number of them up reading a definition similar to the following from Wikipedia at the time of this writing:
In computer science, a thread of execution is the smallest unit of processing that can be scheduled by an operating system. The implementation of threads and processes differs from one operating system to another, but in most cases, a thread is contained inside a process. Multiple threads can exist within the same process and share resources such as memory, while different processes do not share these resources. In particular, the threads of a process share the latter's instructions (its code) and its context (the values that its variables reference at any given moment). To give an analogy, multiple threads in a process are like multiple cooks reading off the same cook book and following its instructions, not necessarily from the same page.

On a single processor, multithreading generally occurs by time-division multiplexing (as in multitasking): the processor switches between different threads. This context switching generally happens frequently enough that the user perceives the threads or tasks as running at the same time. On a multiprocessor (including multi-core system), the threads or tasks will actually run at the same time, with each processor or core running a particular thread or task.
Many modern operating systems directly support both time-sliced and multiprocessor threading with a process scheduler. The kernel of an operating system allows programmers to manipulate threads via the system call interface. Some implementations are called a kernel thread, whereas a lightweight process (LWP) is a specific type of kernel thread that shares the same state and information.

Why isn't the above definition very useful to beginners and only marginally useful to anyone else?

In my opinion, these kinds of definitions are not very useful to anybody because if you can comprehend it then you are already higher up on the learning curve that anyone who would actually need it in the first place.
The problem is that an understanding of threads is not the result of processing the words that make up its definition.  Rather it comes from an understanding of the environment that naturally gives rise to their existance.

How can this be improved upon?
Here's a first stab at a more concise way to saying all this.  The main difference is taht I try to use only words that a beginner would understand. 
  • Computers run programs one instruction at a time.
  • An operating system is a special program that orchestrates the execution of multiple other programs by organizing their instructions in memory and switching rapidly between them at a rate that gives the user an effect of simultaneous execution.
  • A thread is to a process as a process is to an operating system.
It is still up to the student to have a fair amount of mental acuity to process a more abstract description particularly the use of an analogy, so I'm not entirely sure this is an improvement but I do think it's in the direction of one.


Thursday, April 12, 2012

How To Create an Updateable View in SQL Server

Relational databases typically break information into multiple tables to reduce the amount of repeated information they contain.

For example suppose you want to store notes about people.
You could (but probably should not) create a table like this:

create table PeopleNotes (
   name varchar(max)
  ,note varchar(max)
)

The reason this is a bad idea becomes clear when you consider the contents of the table when multiple notes are entered for the same person.

insert into PeopleNotes values
  ('Aaron', 'came to work')
 ,('Joe', 'left eary')
 ,('Aaron', 'posted to his blog')


name     note
-------  -------------
Aaron    came to work
Joe      left eary
Aaron    posted to his blog



The problem with the data in PeopleNotes is that the name "Aaron" is stored two times.  This doesn't seem like a big deal but if there were 1,000,000 notes then it would waste alot of space to repeat those 5 characters of the name over and over for each row.

The solution is to make a second table called People and then change PeopleNotes to store a reference to its id.

create table People (
   id int primary key not null identity(1,1)
  ,name varchar(max)
)


create table PeopleNotes (
   id int primary key not null identity(1,1)
   person_id varchar(max) references People(id)
  ,note varchar(max)
)



id      name
------- -------------
1       Aaron
2       Joe


id      person_id note
------- --------- -------------
1       1         came to work
2       2         left eary
3       1         Aaron posted to his blog


The extra complexity of a second table yields a savings every time a note is added for person that already exists because instead of storing all the characters of the name it just has to store the id of row in the Person table.

Now in order to get the same result a view is created to join the tables together.

create view v_PeopleNotes as
select P.name, N.note
from PeopleNotes N
inner join People P on N.person_id = P.id


The complexity of inserting increases since in order to add a row to PeopleNotes, the People table needs to be checked for the existance of the person's name and added to if not found.

By placing the required logic in an INSTEAD OF INSERT trigger, the insert statement that originally worked with PeopleNotes when it was a single table now works with v_PeopleNotes.

create trigger tr_v_PeopleNotes_IOI on v_PeopleNotes
instead of insert as begin
    set nocount on

    --
    -- insert People
    --
    if(not exists(
      select P.id from People P
      inner join inserted I on P.name = I.name))
         insert into People

         select distinct name from inserted
    --
    -- insert PeopleNotes
    -- 
    insert into PeopleNotes (person_id, note)
    select P.id, I.note
    from People P inner join inserted I on P.name = I.name
end

Tuesday, April 10, 2012

Enterprise Library 5.0 Logging Step by Step Quick Start


Environment / Setup

  • Visual Studio 2010 Professional
  • Visual Studio Extension – NuGet Package Manager
  • Visual Studio Extension – EnterpriseLibrary.Config

Step 1 – Create a console application.

Step 2 – Use NuGet package manager to add the Enterprise Library 5.0 logging assemblies to your project.

  • Open the Package Manager Console
  • Set the package manager default project to your console application.
  • Issue the following package manager command:
    PM> install-package EnterpriseLibrary.Logging

Step 3 – Add an application configuration item (App.config) to your console application.

Step 4 – Configure Enterprise Library 5.0 logging.

  • Launch the Enterprise Library configuration editor.
  • Click BlocksàAdd Logging Settings
  • Save and exit.

Step 5 – Code a log entry.

var logEntry = new Microsoft.Practices.EnterpriseLibrary.Logging.LogEntry();
logEntry.Message = "test log entry 1";
Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write(logEntry);

Step 6 – Try it out.

  • Run the application.
  • Run eventvwr.exe