Extensions:
IEnumerableExtensions
I'll start with an extension method that can benefit everyone, I'm sure I'm not the first to create this but it's by far the most used in any code I write.
/// <summary>
/// Shortcut to items.ToList().ForEach(action);
/// </summary>
public static void Each<T>(this IEnumerable<T> items, Action<T> action)
{
items.ToList().ForEach(action);
}
The ForEach method is only available on List<T>, I believe so I've made a shortcut to it called "Each". Similar to jQuery. :D
Example use:
var people = new[] {
"Peter",
"Louis",
"Chris",
"Meg",
"Stewie"
};
people.Each(Console.WriteLine);
There's a lot of other shortcut methods that just provide better readability IMO. Most of the other extensions don't really need much explanation, however I will add documentation and examples.
Helpers:
SerializationHelper:
I use xml serialization on daily basis, and these methods just wrap the code to do the xml serialization. I feel bad as I grab most of this code from something on someone code project, but it's been so long I can't remember who it was or where I saw it. :/
Example Code coming soom.
Utils:
IQuery
Where I work, they don't use an ORM and sometimes that's the correct choice. In those case you generally have to write a lot of data interaction. A friend developed the code the code that started this class, however after using it I found my self continually writing the same code over and over. That's a key sign that there's probably a better way. The interface IQuery can be used to decouple the database interaction logic.
Checkout how easy writing a handler can become:
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal SellPrice { get; set; }
protected static Product DeserializeProduct(IRow row)
{
var p = new Product();
p.Id = row.GetInt32("ID");
p.Name = row.GetString("NAME");
p.SellPrice = row.GetDecimal("SELL_PRICE");
return p;
}
protected static IQuery Query = new MsSqlQuery("A valid connection string"));
public static IEnumerable<Product> GetProductsByCategory(string category)
{
var sql = @"
SELECT ID,NAME,SELL_PRICE
FROM PRODUCT
WHERE CATEGORY = @Category;
";
var sqlParameters = new[] {
new SqlParameter("@Category", category)
};
var productList = Query.ExecuteSqlForMany(sql, sqlParameters, DeserializeProduct);
return productList;
}
public static Product GetProductById(int id)
{
var procedureName = "GET_PRODUCT_BY_ID";
var parameters = new[] {
new SqlParameter("@id", id)
};
var product = Query.ExecuteProcedureForOne(procedureName, parameters, DeserializeProduct);
return product;
}
}
*Please note I don't advocate the use of placing data access logic in a data model as static methods.. it was just nice for demonstration purposes.
IObjectFactory
So this is my stupidly simple exploration into dependency injection. I tend to use this for small quick projects. The concept is you bind an interface to the an anonymous method containing the logic to instantiate the class.
public class Container {
private static IObjectFactory _objectFactory;
protected static IObjectFactory ObjectFactory
{
get { return _objectFactory ?? (_objectFactory = BuildObjectFactory());
}
protected static IObjectFactory BuildObjectFactory()
{
var o = new ObjectFactory();
o.Bind<IQuery>(() => new MsSqlQuery("A valid Connection string"));
o.Bind<IProductRepository>(() => {
var q = ObjectFactory.Instance<IQuery>();
return new ProductRepository(q);
};
return o;
}
public static T Instance<T>()
{
return ObjectFactory.Instance<T>();
}
public static T New<T>()
{
return ObjectFactory.New<T>();
}
}
Typically I use a pattern like the above to abstract and lazy load the ObjectFactory. I thought it might be cool to try and build an dependency injection container that avoided reflection and stored the constructor invocation instead. Here would be the calling code:
class Program {
public static Main(string[] args)
{
var repo = Container.Instance<IProductRepository>();
var product = repo.GetProductById(42);
Console.WriteLine(product.Name);
}
}
If you're using a singleton pattern for class like Repositories and Services you can call "Instance<T>". If you'd rather get a new object you can use the "New<T>" (this does not change the instance of the object returned by the Instance<T> method).