Nature by Numbers from Cristóbal Vila on Vimeo.
Wednesday, January 26, 2011
Friday, January 14, 2011
Dealing With Assembly versioning
There are 3 attributes that specify version:
AssemblyInformationalVersion -
This shows up as Product Version in Windows Explorer
AssemblyVersion – This is the version number used by framework during build and at runtime to locate, link and load the assemblies
AssemblyFileVersion - This is the version number given to file as in file system. It is displayed by Windows Explorer. Its never used by .NET framework or runtime for referencing.
If You set versioning like: [assembly: AssemblyVersion("1.0.*")], It will increment during build process
You can specify this in AssemblyInfo.cs
Resources:
support.microsoft.com
MSDN Publisher Policy
StackOverFlow
Wednesday, January 12, 2011
Sharepoint GetItemById, GetItemByUniqueId, SPQuery performance
Testing process:
1. Creating ConsoleApplication
2. Getting Test site
3. Creating Test scenarios
4. Run tests and measure performance
Test1: return list.GetItemById(x)
Test2: return list.GetItemByUniqueId(x)
Test3:
SPQuery query = new SPQuery();
query.Query = "<Where><Eq><FieldRef Name=\"ID\"></FieldRef><Value Type=\"Integer\">" + id + "</Value></Eq></Where>";
query.MeetingInstanceId = -2;
query.ItemIdQuery = true;
query.RowLimit = 1;
SPListItemCollection items = list.GetItems(query);
if (items.Count > 0)
{
return items[0];
}
Results and conclusion:
All 3 tests performed about 15ms for each SPListItem, so its about readability or usability witch one to use.
Friday, January 7, 2011
Compare IEnumerable collection of custom objects in Linq
To use Linq : Except, Intersect, etc. on custom Class object collection, you need to provide IEqualityComparer, but is so frustrating, to write a class for each of your objects.
I have found that easiest way to avoid writing custom classes is to write one generic class:
public class Comparer<T> : IEqualityComparer<T>
{
private readonly Func<T, T, bool> _comparer;
public Comparer(Func<T, T, bool> comparer)
{
if (comparer == null) throw new ArgumentNullException("comparer");
_comparer = comparer;
}
public bool Equals(T x, T y)
{
return _comparer(x, y);
}
public int GetHashCode(T obj)
{
return obj.ToString().ToLower().GetHashCode();
}
}
and then You can write like this
IEnumerable<SPRoleAssignment> roles = fromRoles.Except(toRoles, new Comparer<SPRoleAssignment>((a, b) => a.Member.ID == b.Member.ID));
Tuesday, January 4, 2011
Log4Net vs Enterprise Library
In development after deploying application to test servers or production lots of bugs can be discovered only if You implemented a good logging or some logging at all.
I have found that there is 2 products dominating that is Log4Net and Ent.Lib Logging
Today I wanted to test only performance.
Used versions:
Log4Net 1.2.10
Microsoft Enterprise Library 5.0
Visual Studio 2010 Premium
.Net framework 3.5 (Sharepoint does not work with 4.0)
Testing process:
Creating console application that creates 10000 log Info level entries and measure time.
Creating Test Code
class Program
{
static void Main(string[] args)
{
DateTime d = DateTime.Now;
for (int n = 0; n < 10000; n++)
{
//Logging goes here
}
DateTime d2 = DateTime.Now;
Console.WriteLine(string.Concat("Finished: ", (d2-d).Milliseconds, "ms"));
Console.ReadKey();
}
}
Log4Net
1 Adding reference to
bin\net\2.0\release\log4net.dll
2 Configuring
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<log4net>
<param name="File"
<appender name="LogFileAppender" type="log4net.Appender.FileAppender,log4net" >
value="c:\\!\\log4net.txt" />
<param name="AppendToFile" value="true" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] <%X{auth}> - %m%n" />
</layout>
</appender>
<root>
<priority value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
<category name="Log4NetTest.Program">
<priority value="ALL" />
</category>
</log4net>
</configuration>
3. Code
class Program
{
private static readonly ILog log = LogManager.GetLogger(typeof(Program));
static void Main(string[] args)
{
XmlConfigurator.Configure();
DateTime d = DateTime.Now;
for (int n = 0; n < 10000; n++)
{
//Logging goes here
log.Info(n);
}
DateTime d2 = DateTime.Now;
Console.WriteLine(string.Concat("Finished: ", (d2-d).Milliseconds, "ms"));
Console.ReadKey();
}
}
Microsoft Enterprise Library 5.0
1. Adding reference to Ent.Lib
Microsoft Enterprise Library 5.0\Bin\Microsoft.Practices.EnterpriseLibrary.Logging.dll
2. Configuring
3. Code
static void Main(string[] args)
{
DateTime d = DateTime.Now;
for (int n = 0; n < 10000; n++)
{
//Logging goes here
Logger.Write(n);
}
DateTime d2 = DateTime.Now;
Console.WriteLine(string.Concat("Finished: ", (d2 - d).Milliseconds, "ms"));
Console.ReadKey();
}
Results for 10K records (Keeping Log files after each test)
Nr Log4Net Ent.Lib
1 218ms 515ms
2 234ms 468ms
3 203ms 390ms
4 249ms 640ms
5 234ms 390ms
Results for 1M records(Deleted Log files after each test)
Nr Log4Net Ent.Lib
1 107ms 253ms
2 436ms 742ms
3 279ms 241ms
4 216ms 350ms
5 342ms 240ms
Conclusion:
Log4Net is lighter and faster but it lacks configuration manager like Ent.Lib provides. To make configuration file I had to google around and search for examples. Ent.Lib is a little slower, but configuration tool it compensates that with very easy way to create logging for Your application.
Monday, January 3, 2011
Exporting SharePoint web and Importing to same SiteCollection (part 2)
Read (Part 1) before
The problem when You need to change web Url while importing must be solved manualy.
Add Event handler to import procedure.
import.Started += new EventHandler<SPDeploymentEventArgs>(OnSiteImportStarted);
private void OnSiteImportStarted(object sender, SPDeploymentEventArgs args)
{
SPImportObjectCollection rootObjects = args.RootObjects;
if (rootObjects.Count != 0)
{
if (rootObjects.Count != 1)
{
for (int i = 0; i < rootObjects.Count; i++)
{
if (rootObjects[i].Type == SPDeploymentObjectType.Web)
{
rootObjects[i].TargetParentUrl = m_webParentUrl;
rootObjects[i].TargetName = m_webName;
return;
}
}
}
else
{
rootObjects[0].TargetParentUrl = m_webParentUrl;
rootObjects[0].TargetName = m_webName;
}
}
}
Thanks to:
http://blog.falchionconsulting.com/