Wednesday, 13 November 2013

Entityframework reverse POCO generator V2.1 released

Whats new in v2.1.0:
  1. Fixed bug if default constraint was not in expected format. Thanks to Filipe Fujiy.
  2. Now detects name clashes with C# keywords.
  3. Added "System." to DateTime.Now(), etc to prevent clashes with table field names.
  4. "Configuration" class names are now configurable as "Mapping", "Map", etc.
  5. Added support for Spatial.DbGeometry and Spatial.DbGeography. Thanks to Simply Foolish and Jorge Bustos.
  6. Can now have custom collection type for Navigation Properties. "ObservableCollection" for example. Thanks to Simply Foolish.
Watch the video and Download at visualstudiogallery

Tuesday, 12 November 2013

NServiceBus and encrypting strings in messages, plus how to remove NServiceBus from your messages library

Summary

There are a few blog posts about using NServiceBus and encrypting strings using the WireEncryptedString type. However, you can also mark an ordinary string to be encrypted via configuration, which is more desirable as you can remove the dependancy from NServiceBus from your common Messages library.
There is a gotcha though, if you ever mix the two, then WireEncryptedString go back to being unencrypted in MSMQ. This blog post explains how to easily fix this, and also how to remove NServiceBus from your Messages library. Win Win.

Source code is avilable here. Compiling the project will automatically download packages via NuGet.

Initial project setup

Always have a separate Messages project to keep your messages in. In this example, the project is called Messages and contains the following class:
using NServiceBus;
 
namespace Messages
{
    public class MyMessage : IMessage
    {
        public WireEncryptedString Secret1 { getset; }
        public string PlainString { getset; }
    }
}

Note there it inherits from IMessage, and therefore has a dependance on NServiceBus. It also makes use of the WireEncryptedString which again has a dependance on NServiceBus.

Nothing special in the app.config other than to specify the message endpoint as SomeQueueName.
<configuration>
    <configSections>
        <section name="UnicastBusConfig" 
                 type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
    </configSections>
    
    <UnicastBusConfig>
        <MessageEndpointMappings>
            <add Messages="Messages" Endpoint="SomeQueueName" />
        </MessageEndpointMappings>
    </UnicastBusConfig>
</configuration> 

The endpoint configuration specifies that NServiceBus use Rijndael as the encryption service:
public class EndpointConfig : 
    IConfigureThisEndpoint, 
    AsA_Client, 
    IWantCustomInitialization
{
    public void Init()
    {
        Configure.With()
                 .DefaultBuilder()
                 .RijndaelEncryptionService();
    }
}

We also need to setup an encryption key. This is done by the following class:
public class ConfigOverride : 
    IProvideConfiguration<RijndaelEncryptionServiceConfig>
{
    public RijndaelEncryptionServiceConfig GetConfiguration()
    {
        return new RijndaelEncryptionServiceConfig
            {
                // This key could be fetched from a REST/WS call, 
                // Database, or a common xml/settings file.
                Key = "blah.blah.blah.blah.blah.blah..."
            };
    }
}

The final piece is to create a class that will actually send a message:
public class MessageSender : IWantToRunWhenBusStartsAndStops
{
    public IBus Bus { getset; }

    public void Start()
    {
        var msg = new MyMessage
            {
                Secret1 = "You should not be able to read this in MSMQ",
                PlainString = "This is an ordinary string"
            };
        Bus.Send(msg);
        LogManager.GetLogger("MessageSender").Info("Sent message.");
    }

    public void Stop()
    {
    }
}

The resultant message looks like this:
<MyMessage>
    <Secret1>
        <EncryptedValue>
            <EncryptedBase64Value>QcJJfYP2SlOuDYNgFTQ8t8XI5D7zlwQzQXEFk8hcYT7gKUvqxN2Jg1UT7Q1CO929</EncryptedBase64Value>
            <Base64Iv>Q9Dc+k4V4LLPUc5+lEAtOQ==</Base64Iv>
        </EncryptedValue>
    </Secret1>
    <PlainString>This is an ordinary string</PlainString>
</MyMessage>

So far so good.

Now let's mark the PlainString to be encrypted using configuration instead of WireEncryptedString.
The first thing we do is to create a custom attribute we can use to mark strings to be encrypted:
namespace Messages
{
    public class MyEncryptionAttribute : Attribute
    {
    }
}

Then mark the strings to be encrypted:
public class MyMessage : IMessage
{
    public WireEncryptedString Secret1 { getset; }
    
    [MyEncryption]
    public string PlainString { getset; }
}

Next, we need to tell NServiceBus to treat all fields that use MyEncryption attributes to be encrypted:

namespace Sender
{
    public class ConventionsConfiguration : 
        IWantToRunBeforeConfiguration
    {
        public void Init()
        {
            Configure
                .Instance
                .DefiningEncryptedPropertiesAs(type => 
                    type.GetCustomAttributes(true)
                    .Any(t => t.GetType().Name == "MyEncryptionAttribute"));
        }
    }
}

So, run it and lets see what we get:
<MyMessage>
    <Secret1>
        <Value>You should not be able to read this in MSMQ</Value>
    </Secret1>
    <PlainString>k9FJRIfCMmyOW4ev8wytLIg56wEKsSbg1stmSo8Wu44=@XEx7Gkaks5nfhrQAuS2kZw==</PlainString>
</MyMessage>

Whoops!

The PlainString is now encrypted as we want, but in doing so the Secret1 string has become plain text. The Secret1 string is still a WireEncryptedString type and yet it still insists on being plain text, just because we've used the DefiningEncryptedPropertiesAs property on NServiceBus.


Let's fix it

We do this by changing ConventionsConfiguration class to also include the WireEncryptedString type as follows:
public class ConventionsConfiguration : 
    IWantToRunBeforeConfiguration
{
    public void Init()
    {
        Configure
            .Instance
            .DefiningEncryptedPropertiesAs(type =>
                type.PropertyType.Name == "WireEncryptedString" ||
                type.GetCustomAttributes(true)
                .Any(t => t.GetType().Name == "MyEncryptionAttribute"));
    }
}

Running this, the message now appears as:
<MyMessage>
 <Secret1>
  <EncryptedValue>
   <EncryptedBase64Value>4PHC9vcbOID08b8wbCl9tHdv8VH0aW8lFRFYGyHodwFkaV+YzF07aPPeRS3PVSCY</EncryptedBase64Value>
   <Base64Iv>/oFdQX9eTv7WWPJZIRwYsw==</Base64Iv>
  </EncryptedValue>
 </Secret1>
 <PlainString>P5vhzqd3NibLovHYMk8cVI/9k60jVDPERMHRPMMuCmg=@qbwJ2hrdeXegHbkisO4J8w==</PlainString>
</MyMessage>

Voila!

Both strings are now encrypted. You can see they are slightly different in the message.
To access Secret1, you do it via the .Value() method on Secret1. To access the plain unencrypted text on PlainString, you simply access the string as normal. Both strings are encrypted and unencrypted for you by NServiceBus.

How to remove NServiceBus from our Messages library

Now we have a way to tag strings to be encrypted, we can alter our message class to be:
public class MyMessage : IMessage
{
    [MyEncryption]
    public string Secret1 { getset; }
    
    [MyEncryption]
    public string PlainString { getset; }
}

Next we need to remove the IMessage interface, and remove all dependancies from NServiceBus. In a similar fashion to marking strings with attributes, we can mark message classes with an attribute.
public class MessageAttribute : Attribute
{
}

The we tag the message as follows:
[Message]
public class MyMessage
{
    [MyEncryption]
    public string Secret1 { getset; }
    
    [MyEncryption]
    public string PlainString { getset; }
}

NServiceBus now needs to be told which messages it can use. This is done in our ConventionsConfiguration class by adding a call to .DefinishMessageAs() as follows:
public class ConventionsConfiguration : 
    IWantToRunBeforeConfiguration
{
    public void Init()
    {
        Configure
            .Instance
            .DefiningEncryptedPropertiesAs(type =>
                type.PropertyType.Name == "WireEncryptedString" ||
                type.GetCustomAttributes(true)
                    .Any(t => t.GetType().Name == "MyEncryptionAttribute"))
            .DefiningMessagesAs(type =>
                type.GetCustomAttributes(true)
                    .Any(t => t.GetType().Name == "MessageAttribute"));
    }
}

Let's run this to see what the message now looks like:
<MyMessage>
    <Secret1>Rv7L0pDwDlY9KOZQqXuoRPGnD8MxXUJ7dPCOfXnBpP337Egz59aGMY/z6yhW03op@CAeXrzjYBwXYiN2R1iGKrw==</Secret1>
    <PlainString>obwa5exdHIt7AFoQKypzSZIRQR/Q2srJgP3Valej54o=@T09tOdiPjMxFntdI1FJouw==</PlainString>
</MyMessage>

That's it

  1. I've removed all references to NServiceBus from my messages library. So no more messy versioning problems for other projects.
  2. Strings to be encrypted are tagged with an attribute, which we tell NServiceBus about.
  3. Message classes are tagged with an attribute, which we tell NServiceBus about.

Friday, 8 November 2013

What's new roundup for EntityFramework Reverse POCO Code First Generator

Whats in the next version:
  1. Fixed bug if default constraint was not in expected format. Thanks to Filipe Fujiy.
Whats new in v2.0:
  1. Fixed issue when running 'Transform All T4 Templates' from Visual Studio Build Menu. Thanks to JRoselle.
  2. Changing mappings during runtime is not possible/expensive. A specific DbModelBuilder can be used for each needed database schema. Thanks to meixger.
  3. Added ability to detect and use .IsRowVersion().
  4. Added many-to-many mappings. The generated code now includes calls to .Map(). Therefore the generated code will be different to what you had previously in v1 if you have many-to-many table mappings in your database. Hence the revision change to v2.0.0 as I'm using semantic versioning.
Whats new in v1.12:
  1. VARBINARY(MAX) is now correctly assigned to byte[]. Thanks to Luke91577.
  2. Extending partial class support. Allow specification of file extension for partial classes (i.e. ".generated.cs"). Thanks to AB_dreeve.
  3. Fixes issues when targeting .NET 4. .NET 4.0 doesn't include the System.ComponentModel.DataAnnotations.Schema namespace, allow specification of TargetFrameworkVersion. Thanks to AB_dreeve.
Whats new in v1.11:
  1. Including views is now working. For a view to be included, at least one column must not be nullable. Thanks to Delmo Carruzzo.
  2. Added selective generation of components (Poco, Context, UnitOfWork, PocoConfiguration). You can now build entities in your Model project, and context, configuration, unit of work in your Data project.  Thanks to kscelfo.
  3. Added PrependSchemaName flag. You can now control if the schema name is prepended to the table name.  Thanks to kscelfo.
Whats new in v1.10:
  1. Added UseCamelCase flag to the tt file. You can now control if you want your table and column names CamelCase or left alone: i.e. FieldPersonOrder or field_person_order
Whats new in v1.9.2:
  1. Removed the Linq de-duplication code as it is now being done in SQL. The Linq version did not include the schema name when de-duplicating FK's.
Whats new in v1.9.1:
  1. Added DISTICT to the foreign key SQL. This prevents duplicates from appearing.
    They can appear with SQL such as:
    ALTER TABLE [Mars].[Table2] WITH CHECK ADD CONSTRAINT [FK_Table2_Table1]
        FOREIGN KEY([Table1Id]) REFERENCES [Mars].[Table1] ([Id])
    ALTER TABLE [Mars].[Table2] CHECK CONSTRAINT [FK_Table2_Table1] 
    
Whats new in v1.9.0:
  1. It now has the ability to read connection strings from other config files/projects.
    It starts by looking at the local project for the named connection string in the following files:
    • app.config
    • web.config
    • app.config.transform
    • web.config.transform
    • or edit the above list in the .tt and specify which file(s) to use
    If not found, it then looks for those files in all the projects within the solution.
Whats new in v1.8.0:
  1. Can now optionally generate separate files. See the new boolean flag GenerateSeparateFiles.
  2. Removed the hard coded 300 second timeout. The timeout can be specified in the connection string.
Whats new in v1.7.1:
  1. Add support for DateTime2
  2. Add support for UnitOfWork and the repository pattern. This means you can now unit test your repositories. See the source code for examples.
  3. Add IDisposable to db context.
Whats new in v1.7.0:
  1. Add .HasPrecision(precision, scale) for fields that have scale. Thanks to @choudeshell
Whats new in v1.6.0:
  1. Enhance ReadSchema performance with early table exclusion.
  2. Now supports columns with symbols and punctuation.
  3. Handles decimal default values.
Whats new in v1.5.1:
  1. A bugfix for WCF. See issue https://efreversepoco.codeplex.com/workitem/4
Whats new in v1.5.0:
Ability to add WCF(DataMember, DataContract attributes) support on Entity. Requested by spatemp