Posted by Max | Posted in programming | Posted on 02-02-2010
0
Here is a simple .NET class which allows to get a list of custom attributes defined for class or property and check for their presence and access them by type
public class AttributeList : List<Attribute>
{
/// <summary>
/// Gets a list of custom attributes
/// </summary>
/// <param name="propertyInfo"></param>
/// <returns></returns>
public static AttributeList GetCustomAttributeList(ICustomAttributeProvider propertyInfo)
{
var result = new AttributeList();
result.AddRange(propertyInfo.GetCustomAttributes(false).Cast<Attribute>());
return result;
}
/// <summary>
/// Finds attribute in collection by its own type or parents type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T FindAttribute<T>() where T : Attribute
{
return (T)Find(x => typeof(T).IsAssignableFrom(x.GetType()));
}
/// <summary>
/// Finds attribute in collection by its own type or parents type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public List<T> FindAllAttributes<T>() where T : Attribute
{
return new List<T>(FindAll(x => typeof(T).IsAssignableFrom(x.GetType())).Cast<T>());
}
/// <summary>
/// Finds attribute in collection by its own type or parents type
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public List<T> FindAllAttributes<T>(Type implementsType) where T : Attribute
{
return new List<T>(FindAll(x => implementsType.IsAssignableFrom(x.GetType())).Cast<T>());
}
public bool IsAttributeSet<T>() where T : Attribute
{
return FindAttribute<T>() != null;
}
}
And here is a unit test (using MS Test framework) which shows how this helper class could be used
[TestClass]
public class AttributeListTest
{
private interface IAttr {}
private class FirstIAttrAttribute : Attribute, IAttr {}
private class SecondIAttrAttribute : Attribute, IAttr { }
private class NonIAttrAttribute : Attribute { }
[FirstIAttrAttribute]
[SecondIAttrAttribute]
[NonIAttrAttribute]
private class TestClass
{
}
[TestMethod]
public void Test()
{
var attributeList = AttributeList.GetCustomAttributeList(typeof (TestClass));
Assert.IsTrue(attributeList.IsAttributeSet<FirstIAttrAttribute>());
Assert.IsFalse(attributeList.IsAttributeSet<TestClassAttribute>());
Assert.IsInstanceOfType(attributeList.FindAttribute<SecondIAttrAttribute>(), typeof(SecondIAttrAttribute));
// get all attributes implementing IAttr interface
var iAttrList = attributeList.FindAllAttributes<Attribute>(typeof(IAttr));
Assert.AreEqual(2, iAttrList.Count);
// get all attributes derivind from Attribute class
Assert.AreEqual(3, attributeList.FindAllAttributes<Attribute>().Count);
}
}
Posted by Max | Posted in programming | Posted on 20-01-2010
0
Here is a step-by-step instruction how to configure Visual Studio with Team Foundation Server source control to use WinMerge instad of default viewer for file diffs and merging.
The original instruction was taken from Neovolve site
Read the rest of this entry »
Posted by Max | Posted in programming | Posted on 17-12-2009
0
Sometimes you need to generate some test data for demo purspses. Randomizer class allows you to do it easily.
/// <summary>
/// Gets a random value from list
/// </summary>
/// <typeparam name="T"></typeparam>
public class Randomizer<T> : List<T>
{
private static readonly Random Random = new Random();
public T GetValue()
{
return this[Random.Next(Count)];
}
public List<T> GetValues(int listSize)
{
var result = new List<T>();
for(var i=0; i<listSize; i++)
result.Add(GetValue());
return result;
}
}
class Program
{
static void Main()
{
// init list of values
var firstNames = new Randomizer<string> { "Peter", "Paul", "Jane", "Irene", "Michael", "Sara" };
var lastNames = new Randomizer<string> { "Smith", "Doe", "Jackson" };
var dates = new Randomizer<DateTime> { new DateTime(2009,1,1), DateTime.Now, DateTime.Now.AddDays(2) };
// get list of 20 random order values from list of names
firstNames.GetValues(20).ForEach(x => Console.Write("{0}\n", x));
// generate details for 10 users
for(var i=0; i<10; i++)
Console.Write("User: {0} {1} Born: {2}\n", firstNames.GetValue(), lastNames.GetValue(), dates.GetValue());
}
}
Posted by Max | Posted in programming | Posted on 08-12-2009
0
Here is a method to pass class property of value type into method which updates the value of that property. Instead of specifying object instance and property name as a string (which is error prone), it uses LinQ expression. Similar technique is used by Fluent NHibernate to define mappings between database table and .NET class
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleTest
{
public class Values
{
public int X { get; set; }
public int Y { get; set; }
public override string ToString()
{
return String.Format("[ X={0} Y={1} ]", X, Y);
}
}
class Program
{
static void Main()
{
var values = new Values {X = 1, Y = 1};
// pass parameter to be incremented as linq expression
IncrementValue(values, v => v.X);
IncrementValue(values, v => v.X);
IncrementValue(values, v => v.Y);
// Output is: [ X=3 Y=2 ]
Console.Write(values);
}
private static void IncrementValue<T>(T obj, Expression<Func<T,int>> property)
{
var memberExpression = (MemberExpression)property.Body;
var propertyInfo = (PropertyInfo)memberExpression.Member;
// read value with reflection
var value = (int)propertyInfo.GetValue(obj, null);
// set value with reflection
propertyInfo.SetValue(obj, ++value, null);
}
}
}
Posted by Max | Posted in programming | Posted on 04-12-2009
0
The following example uses dynamic factory which returns formatter object for given type using the custom attribite specifying which type is handled by formatter. The factory uses .NET reflection mechamism, rather than a series of “if” or “switch” statements, so the factory class itself is not updated when new formatters added into the solution.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main()
{
var list = new List<object>
{
2.45m,
DateTime.Now,
6m,
DateTime.Now.AddDays(2)
};
foreach (var item in list)
{
var formatter = FormatterFactory.GetFormatter(item.GetType());
Console.WriteLine(formatter.FormattedValue(item));
}
Console.ReadLine();
}
}
/// <summary>
/// Common interface used by formatters
/// </summary>
public interface IFormatter
{
string FormattedValue(object value);
}
/// <summary>
/// This attrubute sets the type is handled by formatter
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class HandlerForTypeAttribute : Attribute
{
public Type Type { get; private set; }
public HandlerForTypeAttribute(Type type) { Type = type; }
}
public static class FormatterFactory
{
private static Dictionary<Type, Type> _typeMapping;
/// <summary>
/// Returns a formatter class instance created by using reflection
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static IFormatter GetFormatter(Type type)
{
if (TypeMapping.ContainsKey(type))
return (IFormatter)Activator.CreateInstance(TypeMapping[type]);
throw new ArgumentException("Not supported type");
}
/// <summary>
/// Returns a list of derived classes for given type
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static IList<Type> GetDerivedClasses(Type type)
{
return (AppDomain.CurrentDomain.GetAssemblies().ToList()
.SelectMany(s => s.GetTypes())
.Where(type.IsAssignableFrom)).ToList();
}
/// <summary>
/// Cached dictionary of mappings between types and their formatters
/// </summary>
private static Dictionary<Type, Type> TypeMapping
{
get
{
if (_typeMapping == null)
{
_typeMapping = new Dictionary<Type, Type>();
// add all classes implementing IFormatter
// interface and having HandlerForType attribute
// into type mapping dictionary
foreach (Type type in GetDerivedClasses(typeof(IFormatter)))
{
var typeAttr = (HandlerForTypeAttribute)Attribute.GetCustomAttribute(
type, typeof(HandlerForTypeAttribute)
);
if (typeAttr != null)
_typeMapping.Add(typeAttr.Type, type);
}
}
return _typeMapping;
}
}
}
/// <summary>
/// Formatter for decimal type
/// </summary>
[HandlerForType(typeof(decimal))]
public class DecimalFormatter : IFormatter
{
public string FormattedValue(object value)
{
return String.Format("Integer value {0:#,###.00}", value);
}
}
/// <summary>
/// Formatter for DateTime type
/// </summary>
[HandlerForType(typeof(DateTime))]
public class DateTimeFormatter : IFormatter
{
public string FormattedValue(object value)
{
return String.Format("DateTime value {0:d}", value);
}
}
// More formatters implementing IFormatter could be added here,
// without the need to change FormatterFactory class
}
Console output:

Posted by Max | Posted in programming | Posted on 03-12-2009
0
CodeRun web based IDE allows you to work with ASP.NET, WPF, Silverlight, Facebook, JavaScript and PHP applications right from your browser. It’s supprising how application interface is similar to Visual Studio.

coderun ide
Posted by Max | Posted in programming | Posted on 11-09-2009
0
There seems to be no any built-in function in SQL Server to format integer value as hexadecimal string. Here is the custom function for SQL server which does that:
For example to the following code displays the value 4095:
SELECT dbo.ToHex(4095) --> FFF
CREATE FUNCTION ToHex(@value int)
RETURNS varchar(50)
AS
BEGIN
DECLARE @seq char(16)
DECLARE @result varchar(50)
DECLARE @digit char(1)
SET @seq = '0123456789ABCDEF'
SET @result = SUBSTRING(@seq, (@value%16)+1, 1)
WHILE @value > 0
BEGIN
SET @digit = SUBSTRING(@seq, ((@value/16)%16)+1, 1)
SET @value = @value/16
IF @value 0 SET @result = @digit + @result
END
RETURN @result
END
GO
Posted by Max | Posted in programming | Posted on 03-09-2009
0
Use the following SQL script to create a table with sequentional numbers. This example inserts 10000 records and performs faster than a similar query using “while” loop.
The original code was taken from here
-- Be sure to drop the numbers table if it exists
IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME='Numbers')
DROP TABLE Numbers
GO
-- Now re-create it and fill it with sequential numbers starting at 1
SELECT TOP 10000 IDENTITY(INT,1,1) AS Num
INTO dbo.Numbers
FROM master.INFORMATION_SCHEMA.COLUMNS i1
CROSS JOIN master.INFORMATION_SCHEMA.COLUMNS i2
CROSS JOIN master.INFORMATION_SCHEMA.COLUMNS i3;
GO
-- Add a primary key/clustered index to the numbers table
ALTER TABLE dbo.Numbers
ADD CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Num);
GO
Posted by Max | Posted in programming | Posted on 09-08-2009
0
These two methods encrypt and decrypt byte array with given key value using DES encryption.
public static class Encryptor
{
public static byte[] Encrypt(byte[] data, string key) {
var stream = new MemoryStream();
var cryptic = new DESCryptoServiceProvider {
Key = Encoding.ASCII.GetBytes(key),
IV = Encoding.ASCII.GetBytes(key)
};
var crStream = new CryptoStream(stream,
cryptic.CreateEncryptor(),
CryptoStreamMode.Write
);
crStream.Write(data, 0, data.Length);
crStream.FlushFinalBlock();
return stream.ToArray();
}
public static byte[] Decrypt(byte[] data, string key) {
var stream = new MemoryStream();
stream.Write(data, 0, data.Length);
stream.Position = 0;
var cryptic = new DESCryptoServiceProvider {
Key = Encoding.ASCII.GetBytes(key),
IV = Encoding.ASCII.GetBytes(key)
};
var crStream = new CryptoStream(stream,
cryptic.CreateDecryptor(),
CryptoStreamMode.Read
);
var plainTextBytes = new byte[data.Length];
int decryptedByteCount = crStream.Read(plainTextBytes,
0, plainTextBytes.Length);
var result = new byte[decryptedByteCount];
for (int i=0; i < decryptedByteCount; i++)
result = plainTextBytes;
return result;
}
}
Posted by Max | Posted in Uncategorized, programming | Posted on 07-08-2009
0
A simple solution if you need to return a paged data from SQL Server stored procedure
CREATE PROCEDURE [dbo].[XXX]
(
@PageSize int = NULL,
@PageNumber int = NULL
)
AS
BEGIN
-- Calculate row number offsets for query.
DECLARE @FirstRow INT, @LastRow INT
SELECT @FirstRow = (@PageNumber - 1) * @PageSize + 1;
SELECT @LastRow = (@PageNumber - 1) * @PageSize + @PageSize;
-- COMMON TABLE EXPRESSION TO PERFORM PAGING LOGIC
WITH QueryResults AS
(
SELECT *,
"RowNumber" = ROW_NUMBER() OVER (ORDER BY UserID ASC)
FROM Users C
)
SELECT *
FROM QueryResults
WHERE RowNumber BETWEEN @FirstRow AND @LastRow
ORDER BY RowNumber ASC
END
GO