C#, Consuming anonymous types at a later point

Last night I was dealing with anonymous types and some IL code to creating and assigning values to instances of anonymous types. I stumbled upon this question:

How do I declare a Field with Anonymous Type (C#)

- http://stackoverflow.com/questions/964334/how-do-i-declare-a-field-with-anonymous-type-c

It didn’t have anything to do with what I was doing but the thing I was doing would solve the issue. I was bringing anonymous types support to ServiceStack.Text, the .Net communities most awesome Serialization framework. Yes I know that the feature already exists in JSON.Net, but when it comes to serialization, I want speed, hence why I turn to ServiceStack.

Alternative 1 – Lets solve the problem using JSON

Step 1 – Install ServiceStack.Text v3.3.6 or later

This feature was introduced in v3.3.6, so use that NuGet.

install-package ServiceStack.Text

Step 2 – Get some data

For this simple demo I will just use some simple person entities that gets yielded.

public class Person
{
	public string Firstname { get; set; }
	public string Lastname { get; set; }
	public int Age { get; set; }
}

public static class Db
{
	public static IEnumerable<Person> Persons()
	{
		yield return new Person
		{
			Firstname = "Hans",
			Lastname = "Wertheim", 
			Age = 30
		};
		yield return new Person
		{
			Firstname = "Daniel", 
			Lastname = "Wertheim", 
			Age = 31
		};
		yield return new Person
		{
			Firstname = "Anton",
			Lastname = "Wertheim", 
			Age = 32
		};
	}
}

Step 3 – Turn it into JSON

Now we need the state turned into JSON. If we want we could transform the data now. Lets combine Firstname and Lastname to Name.

var personsAsJson = Db.Persons()
	.Select(p => new
	{
		p.Age, 
		Name = string.Concat(p.Firstname, " ", p.Lastname)
	})
	.Select(JsonSerializer.SerializeToString)
	.ToArray();

Step 4 – Define a extension method for deserialization

Once we have the JSON blob, we need a deserialization method allowing us to define a anonymous type, used as a template.

public static IEnumerable<T> ToAnonymousType<T>(
	this IEnumerable<string> json, T template) where T : class
{
	TypeConfig<T>.EnableAnonymousFieldSetters = true;
	var templateType = template.GetType();
	return json.Select(j => JsonSerializer.DeserializeFromString(j, templateType) as T);
}

Step 5 – Consume it as we want in another domain

Now, in another domain we could just turn it into a anonymous type of our like. E.g only picking out Name.

var anonymousPersons = personsAsJson.ToAnonymousType(new {Name = default(string)});

foreach (var anonymousPerson in anonymousPersons)
	Console.WriteLine(anonymousPerson.Name);

That’s it. No classes (other than anonymous) used in the tranformations what so ever. Not saying you should, just saying you could.

//Daniel

Tagged , , ,

C#, Why params object[] should be forbidden! (v2)

Edit: This post has been rewritten since I first wrote it. I wrote the first edition in frustration and wasn’t to clear on my point.

Lets start with a sample. First we have a method accepting an int[], using the params keyword. It just tries to output them.

static void Dump1(params int[] ids)
{
	foreach (var id in ids)
		Console.WriteLine(id);
}

Lets consume it

Dump1(1,2,3);
//Outputs
//1
//2
//3

Dump1(new[] { 1, 2, 3 });
//Outputs
//1
//2
//3

Fine. Just what we wanted. The first call passes three values and the second call passes three values, right? No. The last call passes “one” array with three values. But since the Dump1 method accepts params int[], it works.

Now, lets screw things up. Switch params int[] to params object[] and run the same test cases again.

static void Dump2(params object[] ids)
{
	foreach (var id in ids)
		Console.WriteLine(id);
}

Dump2(1,2,3);
//Outputs
//1
//2
//3

Dump2(new[] { 1, 2, 3 });
//Outputs
//System.Int32[]

System.Int32[]

I guess System.Int32 isn’t exactly what you first expect when writing a method like Dump2. Yes, I know there should have been a failing test, but there wasn’t. But there’s a completly other semantic meaning behind passing an int[] array to an params int[] vs to an params object[] array. Of course it shouldn’t be forbidden, that’s a strong word. But it should at least (per default) generate a squiggle in ReSharper ;-)

Now lets finnish with a small tweak. I’ve added a simple recursive extension method. Now we can pass values as we want.

static void Dump(params object[] ids)
{
	foreach (var id in ids.Yield()) //Calling extensionmethod
		Console.WriteLine(id);
}

public static class Extensions
{
	public static IEnumerable<object> Yield(this IEnumerable items)
	{
		if(items == null)
			yield break;

		foreach (var item in items)
		{
			if (item is IEnumerable)
				foreach (var o in Yield(item as IEnumerable))
					yield return o;
			else
				yield return item;
		}
	}
}

Dump(1, 2, 3);
//Outputs
//1
//2
//3

Dump(new[] { 1, 2, 3 });
//Outputs
//1
//2
//3

Dump(new List<int> { 1, 2, 3 });
//Outputs
//1
//2
//3

Dump(new List<int> { 1, 2, 3 });
//Outputs
//1
//2
//3

Dump(1, new[] { 2, 3 }, new[] { new[] { 4, 5 }, new[] { 6, 7 } });
//Outputs
//1
//2
//3
//4
//5
//6
//7

As I said. Off course it should not be forbidden. But, I urge you to think how it will behave when you use params object[].

//Daniel

Tagged ,

SisoDb v9.0 Released.

First lets make one thing clear: “No I’m not chasing Google Chrome versioning!” The reason is that I’m trying to follow Semantic versioning and if there is a change that makes SisoDb more flexible and more performant and it has been asked for, it will go into the codebase. I try to have frequent releases and if it’s a braking change, major version is bumped.

Before going into the meat and the reason for why version 9.0 has been released, lets look at some other stuff. For source code, documentation etc, go to: http://sisodb.com

Denali

The SQL 2008 provider has now been tested against Sql-Server 2012 Express RC0 (Denali) and it works. There will be a separate provider “SisoDb.Sql2012″ for this, but if you want to jumpstart, e.g trying out LocalDb features, you can.

Version 9.0, the Changes

This new version, v9.0, has had two major focus areas:

  • New layout in database for indexes-values
  • Adapt API for coming providers not having Transactions

New layout in database for indexes-values

One major focus has been to rewrite how the key-values that are used for queries, are stored. This is the result of feedback from the community. And as a step in gaining better querying performance, each Indexes table has been divided up amongst seven tables, grouping data that is of the samy type together. By doing this more effective indexes can be designed for enhancing queries and at the same time retain insert speed. I know it sounds like a lot of tables, but hey, Siso should keep you out of the database. And for you that are afraid of limitations, you can read here (http://msdn.microsoft.com/en-us/library/ms143432.aspx), that tables counts as objects and the total number of all objects in a SQL2008 database is as high as 2,147,483,647 objects.

More to come for queries and inserts

There’s plans for making it possible for you to hook in a caching implementation, so that queries doesn’t have to touch the database. In forthcoming release, there will be focus on moving the process of inserting values into the Indexes-tables to a background process. Hence upon inserting items, the structure (document) will be inserted transactional and then the indexes will be queued and inserted in the background. Having done this partitioning by dividing each Indexes-table up in several tables, it will be easier to accomplish parallel inserts.

Text vs String

When you design your model and use properties with string, there’s now from version 9 two different strings. Either you use the normal string BCL type or the custom Text type found in SisoDb. Values from the former will end up in [Entity]Strings table and the later in [Entity]Texts table. Strings has a max length of 300 chars while Text doesn’t. This semantic separation is done so that effective indexes for queries could be created for normal strings, which isn’t feasible if it would be nvarchar(max).

The Text type in SisoDb is implicit convertible to and from a string so you don’t have to use it explicitly other than as a marker on your entity property.

Sample

public class BlogPost
{
    public Guid Id { get; set; }
    public string Title { get; set; } //Ends up in BlogPostStrings
    public Text Content { get; set; } //Ends up in BlogPostTexts
}

var post = new BlogPost 
{
    Title = "A title of max 300 chars",
    Content = "Some long text that can exceed 300 chars."
}

Adapt API for coming providers not having Transactions

In coming realeases, v9.x, SisoDb will have providers that hasn’t support for transactions like the RDBMS environment does. Having UnitOfWork and UnitOfWork.Commit in these providers will not make sense and will probably lead to confusion. Therefore UnitOfWork has changed its name to WriteSession and the QueryEngine is now named ReadSession. Furthermore the UnitOfWork.Commit() method has been removed and auto commit behavior is instead used on UnitOfWork.Dispose(), hence UnitOfWork will still be transactional when you target e.g Sql2008 and SqlCe4. Note!A commit will only be performed if no exception has been encountered.

Old code

using(var unitOfWork = db.CreateUnitOfWork())
{
    unitOfWork.Insert(x);
    unitOfWork.Insert(y);
    unitOfWork.Update(z);
    unitOfWork.Commit();
}

using(var q = db.CreateQueryEngine())
{
    var r = q.Query<Customer>().Where(c => c.CustomerNo == "123456").SingleOrDefault();
}

New code

//As long as the underlying provider supports it, a Write session is still transactional.
using(var session = db.BeginWriteSession())
{
    session.Insert(x);
    session.Insert(y);
    session.Update(z);
} //A Write session is implicitly being committed on Dispose().

using(var q = db.BeginReadSession())
{
    var r = q.Query<Customer>().Where(c => c.CustomerNo == "123456").SingleOrDefault();
}

Other changes

There has also been some other minor adjustments for v9.0 and since SisoDb has evolved kind of rapid lately, chances are that you have missed some features and changes of earlier releases, hence some of them are covered below as well.

DbSchemaNamingPolicy

You can now control the global naming of your structures by register a specific Func against the static DbSchemaNamingPolicy class:

DbSchemaNamingPolicy.StructureNameGenerator = 
    schema => return string.Concat("MyPrefix", schema.Name);

UpdateMany

UpdateMany has been rebuilt to take care of update many operations and not migration operations. As a step, you now have to provide a predicate and UpdateManyStatuses isn’t used anymore to control if an item should be kept or not. Also, the UpdateMany method of the UnitOfWork (now WriteSession) taking an old type and an new type has been removed. To get this functionality there’s a DbStructureSetMigrator you can use instead.

var migrator = Database.GetStructureSetMigrator();
migrator.Migrate<ModelComplexUpdates.Person, ModelComplexUpdates.SalesPerson>((p, sp) =>
{
	var names = p.Name.Split(' ');
	sp.Firstname = names[0];
	sp.Lastname = names[1];

	var address = p.Address.Split(
            new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

	sp.Office.Street = address[0];
	sp.Office.Zip = address[1];
	sp.Office.City = address[2];

	return StructureSetMigratorStatuses.Keep;
});

Custom non generic collections

Actually, this was released as a patch to v8 but I thought it was worth mentioning. As of now you can have custom, non-generic collections.

public class MyModel
{
    public Guid Id { get; set; }
	public MyCollection Items { get; set; }
}

public class MyItem
{
    public int Value { get; set; }	
}

public class MyCollection : List<MyItem> {}

Custom naming of the Id-property

To clean up your models as of v8 you are not forced to name the Id-property “StructureId”. It will look for the following names:

  • StructureId
  • [TypeName]Id
  • Id
  • I[InterfaceName]Id

Machine name specific connectionstrings

This is also a v8 feature and you can now have connectionstring names prefixed with a machine name. When providing a connection string name, Siso will first try to find one with the value you pass but prefixed with Machine name_.

So if you pass “MyConnectionStringName” it will try and find:

  • MachineName_MyConnectionStringName
  • MyConnectionStringName

Case-sensitive collations

I have tested it against a database with a case-sensitive collation setting, and all tests now passes. There was some SQL where members where written in wrong casing but that has now been fixed.

Removed fields

To make the database schema more friendly for manual updates, the hashed value representing an entity has been removed. The SQL queries has also been rewritten so that the RowId columns no longer is needed.

Misc

There has also been some correction of bugs and performance tweaks, regarding some parallel generation of Id’s, structures etc.

Migrate

Take a backup of your database before porting! Below is some info about the changes made to the storage layout, which could be useful. For more info just contact me.

SisoDbIdentities table

The EntityHash column has been dropped and primary-key is instead EntityName. New layout is:

Structures tables

The RowId column and any associated index has been dropped. New layout is:

Indexes tables

You should be able to just make the adjustments to the other tables and then re-save the structures. That should generate the new indexes tables and put values in them. But again. Be ensured you do have a backup.

For manual porting
The values from the indexes tables needs to be inserted in each dedicated indexes-table. Soo values stored in e.g CustomerIndexes IntegerValue column should be stored in CustomerIntegers Value column. Note! That all values (depending on version of SisoDb) has a representation of it’s value in the StringValue column. Hence, when moving values from the StringValue column to CustomerStrings or CustomerTexts you should only move the once that represents a string, which should be the once that has null in every other value column.

Uniques tables

As with the Indexes tables, if you drop this table and re-save all structures the table should be recreated and populated in the correct manners.

Other than that the only change that has been made is that the RowId column has been dropped. New layout is:

That’s it.

//Daniel

Tagged , ,

C#, Parallel deserialization of JSON stored in database

The scenario

A while back ago I had to yield entities constructed by deserializing JSON stored in a database. The first solution just opened a simple single result, sequential reader against the database returning a one column result set containing JSON. This was just yield returned after deserialized to the desired entity. Trying to tweak this I turned to the task parallel library. The idea was to in a separate task, read from the datareader and at the same time in, the main thread, deserialize the JSON string and yield entities while still reading from the database.

The solution

First, lets be clear. I’m not saying you should see this as an solution that fits in all similar scenarios. In my case it was faster reading the strings from the database then doing the deserialization, but it wasn’t to big of a difference, hence there wasn’t that much more memory consumption caused by a large BlockingCollection. But this is something you have to test and measure for your needs. But everything depends on the scenarios. How big is the JSON string? How many items are there? How’s the infrastructure? But lets put that aside and have a look at the solution. The sourceData below comes from yielding the datareader. In a separate task I read from a datareader which represent a single column result set with a string, a JSON. In that task I add the JSON string to a BlockingCollection that wraps the ConcurrentQueue. At the same time in the main thread I TryTake/dequeue a JSON string from the collection and then yield return it deserialized.

When the reading from the database is done, the task is closed and I then deserialize all the non deserialized JSON strings.

public IEnumerable<T> DeserializeManyInParallel<T>(IEnumerable<string> sourceData) where T : class
{
	using (var q = new BlockingCollection<string>())
	{
		Task task = null;

		try
		{
			task = new Task(() =>
			{
				foreach (var json in sourceData)
					q.Add(json);

				q.CompleteAdding();
			});

			task.Start();

			foreach (var e in q.GetConsumingEnumerable())
				yield return JsonSerializer.DeserializeFromString<T>(e);
		}
		finally
		{
			if (task != null)
			{
				Task.WaitAll(task);
				task.Dispose();
			}

			q.CompleteAdding();
		}
	}
}

Again! Measure, test and try it for your scenarios, before accepting it as a solution.

//Daniel

Tagged , , , , ,

C#, Visual Studio 2010, No more Client profile in 5minutes.

I guess I’m not alone being tired of running into the “Client profile” framework version used when creating a Console application in Visual Studio 2010. Don’t know how life is going to be in coming version of Visual Studio, but until then, lets show you a solution that takes no more than 5 minutes.

Step 1 – Locate the Project template shipped with Visual Studio

For me the installation set this up here: C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\ProjectTemplates\CSharp\Windows\1033

Step 2 – Edit the VS-Template file

Unzip the content of ConsoleApplication.zip to a temp location. Rename csConsoleApplication.vstemplate to csConsoleApplication-NoClientProfile.vstemplate. Open the file with a plain old text editor and make the following change. More info: http://msdn.microsoft.com/en-us/library/ms185291.aspx

Original

<?xml version="1.0" encoding="utf-8"?>
<VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
  <TemplateData>
    <Name Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="2320" />
    <Description Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="2321" />
    <Icon Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="4548" />
    <TemplateID>Microsoft.CSharp.ConsoleApplication</TemplateID>
    <ProjectType>CSharp</ProjectType>
    <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>
    <SortOrder>12</SortOrder>
    <NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp>
    <CreateNewFolder>true</CreateNewFolder>
    <DefaultName>ConsoleApplication</DefaultName>
    <ProvideDefaultName>true</ProvideDefaultName>
  </TemplateData>
  <TemplateContent>
    <Project File="ConsoleApplication.csproj" ReplaceParameters="true">
      <ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
      <ProjectItem ReplaceParameters="true" OpenInEditor="true">Program.cs</ProjectItem>
      <ProjectItem ReplaceParameters="true">App.config</ProjectItem>
    </Project>
  </TemplateContent>
</VSTemplate>

Change this
Provide new tags for:

<Name>
<Description>

Remove the tag:

<TemplateId>

Updated

<?xml version="1.0" encoding="utf-8"?>
<VSTemplate Version="3.0.0" Type="Project" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
  <TemplateData>
    <Name>ConsoleApplication-NoClientProfile</Name>
    <Description>Ordinary Console application but NO CLIENT PROFILE</Description>
    <Icon Package="{FAE04EC1-301F-11d3-BF4B-00C04F79EFBC}" ID="4548" />
    <ProjectType>CSharp</ProjectType>
    <RequiredFrameworkVersion>2.0</RequiredFrameworkVersion>
    <SortOrder>12</SortOrder>
    <NumberOfParentCategoriesToRollUp>1</NumberOfParentCategoriesToRollUp>
    <CreateNewFolder>true</CreateNewFolder>
    <DefaultName>ConsoleApplication</DefaultName>
    <ProvideDefaultName>true</ProvideDefaultName>
  </TemplateData>
  <TemplateContent>
    <Project File="ConsoleApplication.csproj" ReplaceParameters="true">
      <ProjectItem ReplaceParameters="true" TargetFileName="Properties\AssemblyInfo.cs">AssemblyInfo.cs</ProjectItem>
      <ProjectItem ReplaceParameters="true" OpenInEditor="true">Program.cs</ProjectItem>
      <ProjectItem ReplaceParameters="true">App.config</ProjectItem>
    </Project>
  </TemplateContent>
</VSTemplate>

Step 3 – Edit the CS-project file

Locate this section:

$if$ ($targetframeworkversion$ >= 4.0)
  <TargetFrameworkProfile>Client</TargetFrameworkProfile>
$endif$

and remove Client.

$if$ ($targetframeworkversion$ >= 4.0)
  <TargetFrameworkProfile></TargetFrameworkProfile>
$endif$

Step 4 – Zip and “install” the new template

Rezip the extracted files from Step 2 into a new file ConsoleApplication-NoClientProfile.zip and drop it into the folder that holds custom project templates for Visual Studio. For me this was: C:\Users\sedanwer\Documents\Visual Studio 2010\Templates\ProjectTemplates\Visual C#

More info: http://msdn.microsoft.com/en-us/library/y3kkate1.aspx

Step 5 – Consume it

The next time you start Visual Studio 2010 and do File – New project, you will now find your now project template under CSharp – Windows.

That’s it. Have fun!

//Daniel

Tagged , , ,

C#, Generic factory with support for private constructors

Today I got involved in a small question on Twitter on how to create a generic factory creating instances of classes having a private constructor. So I put together a small sample that shows a two solutions:

  • Using Activator (around 22s per 100000)
  • Using compiled lambdas (around 8s per 100000)

The example lets you time the difference between the solutions. And feel free to add the code using IL. Please note! This was something I put together really quick so there’s probably some room left for you to tweak.

The source code is also made availible as a Gist here: https://gist.github.com/1529618

Sample model

public interface IPerson
{
	string Name { get; set; }
}

public class Person : IPerson 
{
	public string Name { get; set; }

	private Person() { }
}

The factory

public static class Factory<T> where T : class 
{
	private static readonly Func<T> FactoryFn;

	static Factory()
	{
		//FactoryFn = CreateUsingActivator();

		FactoryFn = CreateUsingLambdas();
	}

	private static Func<T> CreateUsingActivator()
	{
		var type = typeof(T);

		Func<T> f = () => Activator.CreateInstance(type, true) as T;

		return f;
	}

	private static Func<T> CreateUsingLambdas()
	{
		var type = typeof(T);

		var ctor = type.GetConstructor(
			BindingFlags.Instance | BindingFlags.CreateInstance |
			BindingFlags.NonPublic,
			null, new Type[] { }, null);

		var ctorExpression = Expression.New(ctor);
		return Expression.Lambda<Func<T>>(ctorExpression).Compile();
	}

	public static T Create(Action<T> init)
	{
		var instance = FactoryFn();

		init(instance);

		return instance;
	}
}

The test app

class Program
{
    static void Main(string[] args)
    {
		//TOUCH ONCE BEFORE TIMING
		var touchedPerson = Factory<Person>.Create(p => p.Name = "Daniel");

		for (var a = 0; a < 5; a++)
		{
			var sw = Stopwatch.StartNew();
			for (int c = 0; c < 100000; c++)
			{
				var person = Factory<Person>.Create(p => p.Name = "Daniel");
				var n = person.Name;
			}
			sw.Stop();
			Console.WriteLine(sw.Elapsed.TotalMilliseconds);
		}
		Console.ReadKey();
    }
}

That’s it. Enjoy!

//Daniel

Tagged , , , , ,

Kiwi – brings your GitHub Wiki to your custom website

Kiwi is targeting one thing:

To enable you to easily bring your GitHub Wiki content, with its GitHub flavored markdown syntax, to your own site.

As of now, Kiwi only contains one module/component, “Kiwi.Markdown”.

It enables you to point to a directory with Markdown files and then turns them into HTML, with support for GitHub flavored markdown like CSharp code blocks.

Kiwi.Markdown relies on other open source components to handle most of the markdown transformations and syntax highlighting:

For latest version or more info, look at the Kiwi-projects Wiki.

Setup a Controller

For this example I will use a live one. The GitHub Wiki for SisoDb which also has the wiki at http://sisodb.com/wiki

My controller is really simple. One Action and a cache profile, nothing more.

WikiController

[HandleError]
public class WikiController : Controller
{
    [OutputCache(CacheProfile = "WikiCache")]
    public ActionResult Doc(string docId)
    {
        return View(MvcApplication.MarkdownService.GetDocument(docId));
    }
}

Web.config

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="WikiCache" duration="3600" varyByParam="docId"/>
    </outputCacheProfiles>
  </outputCacheSettings>
</caching>

Fix a route

My route is going to match http://sisodb.com/wiki and http://sisodb.com/wiki/{docid} where docId matches the name of the Markdown file except the file suffix.

Global.asax

routes.MapRoute(
    "Wiki", // Route name
    "wiki/{docId}", // URL with parameters
    new { controller = "wiki", action = "doc", docId = "home" } // Parameter defaults
);

Setup a MarkdownService

A bit temporary, but as for now I’ve just put a static member in Global.Asax.

MarkdownService = new MarkdownService(new FileContentProvider(Server.MapPath("~/App_Data/MarkdownFiles"));

You can also see that I have decided to reside my Markdow files under “~/App_Data/MarkdownFiles”. There’s nothing stopping you from using MarkdownService outside a webbapplication, it has no dependencies on any web stack.

Get the Markdown files

Go to the Wiki at your GitHub project and check under Git Access example. Bring down the files using git clone

Take the files and put them in the ASP.Net MVC application’s folder containing Markdown files (App_Data/Markdownfiles).

Tip

When moving the files to a server, you can use the strengths and features of Git.

# Clone and Get the Wiki locally
git clone git://github.com/danielwertheim/Kiwi.wiki.git

# Create a Zip which you can upload
git archive master --format=zip -o Kiwi-Package.zip

Setup the view

Wiki/Doc.cshtml

@using Kiwi.Markdown
@model Document

@{
    ViewBag.Title = @Model.Title;
}

<div class="post">
    <h1 class="title">@Model.Title</h1>

    <div class="entry">@Html.Raw(Model.Content)</div>
</div>

That’s it. Nothing more. There will be other Kiwi components coming that will assist you with the publishing etc of new Markdown files.

Coming feature

I’m working on a small MVC area that will let you complement the flow above with something like:

# Upload the Zip using Curl
curl --upload-file package=@Kiwi-New.zip http://sisodb.com/kiwi/package/put

Of course, the example above misses out setting headers for security, info but I guess you get the point.

Tagged , , , ,

SisoDb reached v4.0.0 – now supports SqlCe4

SisoDb has now reached v4.0.0 and it has gone throw some heavy changes. Let’s take a look at the release notes.

Release notes

v4.0
Major rewrite. The generation of StructureSchemas and Structures (graph of indexes) now lives in project: PineCone. http://github.com/danielwertheim/pinecone
The querying table (Indexes) is now key-value which will open up for better querying support.
Reworked internals to become more generic to simplify writings of additional providers.

[Fixed]     A connection could sometimes get left in a open state.
[Fixed]     Bug when Including other Json documents in the same result (Merged Documents).
[Updated]   ServiceStack.Text updated from v2.2.7 to v3.0.0.
[Updated]   SisoId is now StructureId both in classes as well as in storage schema.
[Updated]   Storage schema for Indexes are now key-value.
[Updated]   Storage schema for Uniques now have UqMemberPath instead of UqName
[Updated]   All members of QueryEngine and UnitOfWork taking Enumerable of Ids, now takes param array of ids instead. E.g. GetByIds, DeleteByIds etc
[Updated]   StructureSetUpdater should not be used individually, but via Database.UpdateStructureSet.
[Updated]   The support for how Uniques are handled has been changed. The property marked as unique is turned into a hashed string before stored. That way we get uniformed lenght strings.
[Updated] 	As a security precausion, DeleteByIdInterval is now only supported when you use Identities and not Guids.
[New]       SqlCE4 support, except from TransactionScopes. Support is on its was. NORMAL TRANSACTIONS ARE OF COURSE SUPPORTED THOUGH!
[New]       The Id (previous SisoId) now StructureId now does support Guid, int, long and Nullable, Nullable, Nullable
[New]       HashSets and Dictionaries are now supported
[New]       Extensionpoints for QueryEngine and UnitOfWork now exists on ISisoDataBase via ReadOnce() and WriteOnce(). These simpliefies working with QueryEngine/UnitOfWorks BUT SHOULD ONLY BE USED WHEN DOING ONE OPERATION AGAINST QueryEngine or UnitOfWork.

It’s not backwards compatible, hence v.4.0.0

No, it’s not backwards compatible. The underlying database schema that previously had a flattened view of your structures now is key-values. Why? Well, I wan’t the ability of constructing SQL queries that supports nested enumerables etc. Of course, the key-value solution will cause a hit in the performance, but if it’s really critical to you, you can turn off indexing for the members you don’t query on.

I will start updating the documentation shortly at SisoDb.Com

//Daniel

Tagged

Security is also about education

Today I was seeing a doctors office part of the geographical region of Västra Götaland, which is somewhat unimportant, except that I wan’t you to understand that the “local doctors office” is part of a bigger organisation. This organisation spends a lot of time securing their data and I have no issue with trusting them of taking care of my journal.

So, this morning when I was in a treatment room, the nurse had to go get a throat testing kit. I was left in the room, all alone, with a closed door for about four to five minutes. In the room there was a workstation, currently displaying my journal. Yes, it was unlocked! And it wasn’t only unlocked, in the workstation’s card reader, the security card used for authorization within the organisation was still left. Not knowing that much about how locked down their terminals are and how hard it would be to “skim” the card, but even so, I think that this shows how week security is. You can spend huge resources on software and hardware, but still have the lousiest security, if you don’t educate your employees in a secure use of the IT equipment.

Don’t just spend money on infrastructure. Spend money on education of your employees to. I’ve been at organisations where you even had to take a course + exam just to access the Internet. You might think that a programmer would gain this level of trust from the beginning. But do you know what? I was all fine with it. It shows me that they are serious about their business. You should to.

//Daniel

Tagged ,

Keyboard shortcuts in code using WPF MVVM and Caliburn Micro

Recently I had to replace a keyboard-shortcut solution in a WPF application where the existing solution used a global hook using unmanaged code. My first tryout was using the ComponentDispatcher. At first, it seemed ok, but sometimes commands wasn’t intercepted and sometimes modifier-keys wasn’t cleared from the buffer. Lets just say “there were problems”. I then turned to simple InputBindings. And since the application used Caliburn Micro, it was quite easy:

Step 1 – Hook up

Extend Screen in a custom ViewModelBase and override OnViewLoaded, extract a Window from the view being loaded and hook up KeyBindings to its InputBindings-collection.

protected override void OnViewLoaded(object view)
{
	base.OnViewLoaded(view);

	var window = (view as FrameworkElement).GetWindow();
	_inputBindings = new InputBindings(window);
	_inputBindings.RegisterCommands(GetInputBindingCommands());
}

In the same ViewModelBase, add a method to return InputBindingCommands that each view model should implement.

protected virtual IEnumerable<InputBindingCommand> GetInputBindingCommands()
{
	yield break;
}

To get hold of the Window (which is where we wan’t to add our input bindings) we just use some traditional recursion to traverse the tree:

{
	public static Window GetWindow(this FrameworkElement element)
	{
		if (element == null)
			return null;

		if (element is Window)
			return (Window)element;

		if (element.Parent == null)
			return null;

		return GetWindow(element.Parent as FrameworkElement);
	}
}

To support overriding previously registered bindings we need to keep track of the input bindings associated with the current view, and to reverse the registration process we just have to stash them away in a stack.

public class InputBindings
{
	private readonly InputBindingCollection _inputBindings;
	private readonly Stack<KeyBinding> _stash;

	public InputBindings(Window bindingsOwner)
	{
		_inputBindings = bindingsOwner.InputBindings;
		_stash = new Stack<KeyBinding>();
	}

	public void RegisterCommands(IEnumerable<InputBindingCommand> inputBindingCommands)
	{
		foreach (var inputBindingCommand in inputBindingCommands)
		{
			var binding = new KeyBinding(inputBindingCommand, inputBindingCommand.GestureKey, inputBindingCommand.GestureModifier);

			_stash.Push(binding);
			_inputBindings.Add(binding);
		}
	}

	public void DeregisterCommands()
	{
		if (_inputBindings == null)
			return;

		foreach (var keyBinding in _stash)
			_inputBindings.Remove(keyBinding);
	}
}

Step 2 – Specify commands

Easy, just override the GetInputBindingCommands method in each ViewModel you want to provide key-commands:

protected override IEnumerable<InputBindingCommand> GetInputBindingCommands()
{
	yield return new InputBindingCommand(NewWindow)
	{
		GestureModifier = ModifierKeys.Control,
		GestureKey = Key.N
	};
}

Step 3 – Clean up

The last step is to cleanup when a view is being deactivated. In the ViewModelBase, just add:

protected override void OnDeactivate(bool close)
{
	base.OnDeactivate(close);

	_inputBindings.DeregisterCommands();
}

The DeregisterCommands method will remove the inputbindings that are associated with the view and added to the window.

Wrap up

Well, I will not show more code. There’s a simple sample app available here: https://github.com/danielwertheim/InputBindingCommand-Lab

//Daniel

Tagged , , , , ,
Follow

Get every new post delivered to your Inbox.