var json = "{\"name\": \"Joe\"," +
"\"age\": 25," +
"\"address\": {\"city\": \"Paris\"}," +
"\"emails\": [\"joe@home.com\", \"joe@work.com\"]," +
"\"phones\": [{\"type\": \"Mobile\", \"number\": \"555 1234\"}]}";
var prototype = new
{
name = default(string),
age = default(int),
address = new {city = default(string)},
emails = new string[0],
phones = new[] {new {type = default(string), number = default(string)}}
};
var result = SimpleJsonExt.DeserializeAnonymousObject(json, prototype);
using CacheEntry = KeyValuePair<ParameterInfo[], ReflectionUtils.ConstructorDelegate>;
public static class SimpleJsonExt
{
public static T DeserializeAnonymousObject<T>(string json, T prototype)
{
return SimpleJson.SimpleJson.DeserializeObject<T>(json, new Strategy());
}
private class Strategy : PocoJsonSerializerStrategy
{
private readonly IDictionary<Type, CacheEntry> _ctorCache =
new ReflectionUtils.ThreadSafeDictionary<Type, CacheEntry>(CreateConstructorDelegate);
private static CacheEntry CreateConstructorDelegate(Type key)
{
var ctors = key.GetConstructors();
if (ctors.Length == 1)
{
var ctor = ctors[0];
var parms = ctor.GetParameters();
if (parms.Length > 0)
{
return new CacheEntry(parms, ReflectionUtils.GetContructor(ctor));
}
}
return default(CacheEntry);
}
public override object DeserializeObject(object value, Type type)
{
var dict = value as IDictionary<string, object>;
if (dict != null)
{
var ctor = _ctorCache[type];
if (ctor.Key != null)
{
return ctor.Value(ctor.Key
.Select(param => DeserializeObject(
dict.TryGetValue(param.Name, out value) ? value : null,
param.ParameterType))
.ToArray());
}
}
return base.DeserializeObject(value, type);
}
}
}
SimpleJson
Tuesday, April 8, 2014
Deserialize an anonymous type using SimpleJson
Sunday, November 24, 2013
Recursively search and replace files from one folder into another
$filter = '*.dll', '*.pdb'
$copied = 0; $skipped = 0; $failed = 0
$sourceFiles = $filter | % { Get-ChildItem $sourceDir -Filter $_ -Recurse } `
| sort @{expression={$_.FullName.Length}} -Descending `
| group Name -AsHashTable
$targetFiles = $filter | % { Get-ChildItem $targetDir -Filter $_ -Recurse } `
| ? { $sourceFiles.ContainsKey($_.Name) } `
| sort FullName
$targetFiles | % {
$target = $_
$sourceFiles[$target.Name] | % {
$source = $_
if ($target.FullName.EndsWith($source.FullName.Substring($sourceDir.Length),
'InvariantCultureIgnoreCase')) {
if ($target.LastWriteTime.AddSeconds(2) -lt $source.LastWriteTime) {
Write-Host $target.FullName
try {
Copy-Item $source.FullName $target.FullName -Force
$copied++
}
catch {
Write-Error $_.Message
$failed++
}
}
else {
$skipped++
}
return
}
}
}
Write-Host "$copied copied, $skipped skipped, $failed failed in $($watch.Elapsed)"
Thursday, March 14, 2013
Programmatically configure a simple log4net trace appender
var hierarchy = (Hierarchy) LogManager.GetRepository();
var logger = (Logger) hierarchy.GetLogger(loggerName);
logger.Level = Level.Debug;
logger.AddAppender(new TraceAppender {Layout = new SimpleLayout()});
hierarchy.Configured = true;
log4net
Monday, January 28, 2013
Convert an SQL like pattern into a regular expression pattern
var pattern = Regex.Replace(
likePattern,
@"[%_]|\[[^]]*\]|[^%_[]+",
match =>
{
if (match.Value == "%")
{
return ".*";
}
if (match.Value == "_")
{
return ".";
}
if (match.Value.StartsWith("[") && match.Value.EndsWith("]"))
{
return match.Value;
}
return Regex.Escape(match.Value);
});
Saturday, January 12, 2013
Load test a web site using asynchronous requests and the TPL
var queue = new Queue<Task>();
while (true)
{
if (queue.Count >= 50)
{
var task = queue.Dequeue();
task.Wait();
task.Dispose();
}
var request = (HttpWebRequest) WebRequest.Create(url);
var watch = Stopwatch.StartNew();
queue.Enqueue(Task.Factory
.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null)
.ContinueWith(task =>
{
using (var response = (HttpWebResponse) task.Result)
{
Console.WriteLine("{0}\t{1}\t{2}",
response.StatusCode, response.ContentType, watch.Elapsed);
}
}));
}
Task Parallel Library (TPL)
Thursday, June 28, 2012
Calculate the exponential moving average of a stream of numbers
public static IEnumerable<double> ExponentialMovingAverage(this IEnumerable<double> source, double alpha)
{
double? last = null;
return source.Select(
value =>
{
var average = last != null ? alpha*value + (1 - alpha)*last.Value : value;
last = average;
return average;
});
}
Thursday, February 16, 2012
Create a fast compiled method invoker using LINQ
var method = new Func<double, double, double>(Math.Pow).Method;
var parameter = Expression.Parameter(typeof(object[]));
var args = method.GetParameters()
.Select((param, i) => Expression.Convert(
Expression.ArrayIndex(parameter, Expression.Constant(i)), param.ParameterType));
var expr = Expression.Lambda<Func<object[], object>>(
Expression.Convert(Expression.Call(method, args), typeof(object)), parameter);
var invoker = expr.Compile();
var result = invoker(new object[] {Math.PI, 2.0});
Friday, February 10, 2012
Create a Google calendar event in an existing calendar
var credentials = new GDataCredentials(userName, password);
var service = new CalendarService(null) {Credentials = credentials};
var query = new CalendarQuery("https://www.google.com/calendar/feeds/default/owncalendars/full");
var feed = service.Query(query);
var eventFeedLink = feed.Entries.Cast<CalendarEntry>()
.Where(item => item.Title.Text == calendarName)
.SelectMany(item => item.Links)
.First(link => link.Rel == GDataParserNameTable.NSGCal + "#eventFeed");
var entry = new EventEntry(title) {Times = {new When(start, end, allDay)}};
service.Insert(new Uri(eventFeedLink.AbsoluteUri), entry);
Google Data API .NET client library
Thursday, February 2, 2012
Page through potentially large NHibernate criteria query results
public static IEnumerable<T> Enumerate<T>(this ICriteria criteria, int pageSize = 1000)
{
var entityCount = CriteriaTransformer.TransformToRowCount(criteria).UniqueResult<int>();
var pageCount = (int) Math.Ceiling(entityCount/(double) pageSize);
criteria = CriteriaTransformer.Clone(criteria).SetMaxResults(pageSize);
return Enumerable.Range(0, pageCount)
.SelectMany(pageNum => criteria.SetFirstResult(pageNum*pageSize).List<T>());
}
NHibernate
Friday, January 20, 2012
Create a YouTube playlist containing all the uploads of a given user
var credentials = new GDataCredentials(userName, password);
var service = new YouTubeService(applicationName, developerKey) {Credentials = credentials};
var entry = new AtomEntry {Title = {Text = playlistName}};
entry = service.Insert(new Uri(YouTubeQuery.CreatePlaylistsUri(null)), entry);
var id = ((XmlExtension) entry.FindExtension("playlistId", YouTubeNameTable.NSYouTube)).Node.InnerText;
var batchUri = new Uri(string.Format("https://gdata.youtube.com/feeds/api/playlists/{0}/batch", id));
var query = new YouTubeQuery(YouTubeQuery.CreateUserUri(sourceUser)) {StartIndex = 1};
AtomFeed feed;
do
{
feed = service.Query(query);
service.Batch(feed, batchUri);
query.StartIndex += feed.Entries.Count;
} while (query.StartIndex < feed.TotalResults);
Google Data API .NET client library
Sunday, January 8, 2012
List the users of a TFS project associated with a local workspace path
var workspace = Workstation.Current.GetLocalWorkspaceInfo(path);
var tfs = new TfsTeamProjectCollection(workspace.ServerUri);
var gss = tfs.GetService<IGroupSecurityService>();
var grp = gss.ReadIdentity(SearchFactor.EveryoneApplicationGroup, null, QueryMembership.Expanded);
var names = gss.ReadIdentities(SearchFactor.Sid, grp.Members, QueryMembership.None)
.Where(identity => identity.Type == IdentityType.WindowsUser)
.Select(identity => string.Format(@"{0}\{1}", identity.Domain, identity.AccountName))
.ToArray();
Friday, January 6, 2012
Quartz scheduler job that re-triggers itself on completion
public class RetriggerJob : IInterruptableJob
{
private bool _interrupted;
public void Execute(IJobExecutionContext context)
{
Thread.Sleep(1000);
if (_interrupted)
{
return;
}
context.Scheduler.TriggerJob(context.JobDetail.Key);
if (_interrupted)
{
context.Scheduler.Interrupt(context.JobDetail.Key);
}
}
public void Interrupt()
{
_interrupted = true;
}
}
Quartz.NET
Friday, December 30, 2011
Read a published Google spreadsheet into a DataTable using GData
var service = new SpreadsheetsService(null);
var query = new ListQuery("0AjD5UGMt5CGDdEcwaS10S2IzVzJFNDYtaEo5anN2RHc", "1", "public", "values");
var feed = service.Query(query);
var table = new DataTable();
foreach (ListEntry entry in feed.Entries)
{
var row = table.NewRow();
foreach (ListEntry.Custom element in entry.Elements)
{
var column = table.Columns[element.LocalName] ??
table.Columns.Add(element.LocalName);
row[column] = element.Value;
}
table.Rows.Add(row);
}
Google Data API .NET client library
Saturday, December 17, 2011
Determine if a WinForms control resource file is localized
XPathDocument doc;
using (var stream = File.OpenRead(fileName))
{
doc = new XPathDocument(stream);
}
var nav = doc.CreateNavigator();
var itr = nav.Select("root/data[@name = '>>$this.Name']");
var localized = itr.Count > 0;
Remove matching C# region directives using LINQ
var flag = false;
var modified = false;
var lines = File.ReadLines(fileName)
.Where(line =>
{
if ((!flag && line.Contains("#region " + regionName)) ||
(flag && line.Contains("#endregion")))
{
flag = !flag;
modified = true;
return false;
}
return true;
})
.ToArray();
if (modified)
{
File.WriteAllLines(fileName, lines);
}
Thursday, December 8, 2011
Compile and execute a stateful T4 template using Mono.TextTemplating
var input =
"<#@ template language=\"C#\" debug=\"true\" #>" +
"<#+ static int num; #>" +
"<#= num++ #>";
var generator = new TemplateGenerator();
var compiled = generator.CompileTemplate(input);
Debug.Assert(Equals(compiled.Process(), "0"));
Debug.Assert(Equals(compiled.Process(), "1"));
Debug.Assert(Equals(compiled.Process(), "2"));
Mono.TextTemplating
Subscribe to:
Posts (Atom)