Tag Archives: Breaking Change

MicroLite.Extensions.Mvc 6.3.0

MicroLite.Extensions.Mvc 6.3.0 has been released on NuGet.

The main changes in this release are:

  1. .NET 4.5 only build targeting ASP.NET MVC 5.2.3
  2. MicroLiteSessionAttribute has been removed, it is strongly recommended that you use an IOC container to manage dependencies.

This does mean that the release is not necessarily a “drop-in” update if you were previously using an older version of .NET or ASP.NET MVC.

To see the full set of changes, please refer to the Github release page

Advertisements

MicroLite.Extensions.WebApi 6.5.0

MicroLite.Extensions.WebApi 6.5.0 has been released on NuGet.

The main changes in this release are:

  1. .NET 4.5 only build targeting ASP.NET WebApi 5.2.3 and Net.Http.WebApi.OData 3.4.0
  2. MicroLiteSessionAttribute has been removed, it is strongly recommended that you use an IOC container to manage dependencies.

This does mean that the release is not necessarily a “drop-in” update if you were previously using an older version of .NET or ASP.NET WebApi.

To see the full set of changes, please refer to the Github release page

Upgrading to MicroLite 6.2

MicroLite 6.2.0 has been released on NuGet.

The 2 main changes in this release are:

  • The session re-uses the same command during its lifecycle so multiple operations via a session are more efficient – especially multiple operations of the same type (e.g. multiple inserts).
  • Improved the handling of TimeSpan – beware that this is a breaking change (see below)

Prior to MicroLite 6.2, MicroLite was able to map a TimeSpan to a MS SQL Time column – however it turns out there are a number of problems with the Time type:

  1. It has a maximum value of 24:00:00 since it is actually designed to represent the time of day
  2. It cannot be used in some aggregate functions such as SUM and AVERAGE which makes summarising data diffucult

In order to mitigate these issues, MicroLite 6.2 now maps TimeSpan to a BIGINT by persisting the tick count of the TimeSpan – this has the added benefit of also enabling TimeSpan to be used by any database supported by MicroLite.

If you are updating to MicroLite 6.2 and you are currently using TimeSpan -> TIME you have 2 options:

1) – Update your database schema to use a BIGINT (add a new column, populate it by casting the time as the tick count, remove the old column).

2) – Configure MicroLite 6.2 to behave like MicroLite 6.1:

// In startup code (before calling Configure.Fluently()...):

// 1. Remove the new TimeSpanTypeConverter:
var timeSpanTypeConverter = TypeConverter.Converters.OfType<TimeSpanTypeConverter>().Single();
TypeConverter.Converters.Remove(timeSpanTypeConverter);

// 2. Reset the DbType mapping for TimeSpan:
TypeConverter.RegisterTypeMapping(typeof(TimeSpan), System.Data.DbType.Time);
TypeConverter.RegisterTypeMapping(typeof(TimeSpan?), System.Data.DbType.Time);

MicroLite 5.0 – Changes to Convention Mapping

In MicroLite 5.0, we are making further enhancements to the convention based mapping which provide even greater flexibility.

Convention Mapping History:

The changes in MicroLite 5.0 are as follows:

ResolveIdentifierStrategy

We have replaced the IdentifierStrategy property with the ResolveIdentifierStrategy method. This means that you no longer have to use the same IdentifierStrategy for every class (or that you can migrate from attribute mapping to convention mapping if this was preventing you from doing so).

By default it will return IdentifierStrategy.DbGenerated but you can override it if you want to specify a different strategy or calculate it based upon the type:

Configure.Extensions().WithConventionBasedMapping(
    new ConventionMappingSettings
    {
        ResolveIdentifierStrategy = (Type type) => 
        {
            if (type == typeof(MySpecialType))
            {
                return IdentifierStrategy.Assigned;
            }

            return IdentifierStrategy.DbGenerated; 
        }
    });

ResolveTableSchema

We have replaced the TableSchema property with the ResolveTableSchema method. This means that you no longer have to use the same schema for every class (or that you can migrate from attribute mapping to convention mapping if this was preventing you from doing so).

By default it will return null but you can override it if you want to specify a specific schema or calculate it based upon the type:

Configure.Extensions().WithConventionBasedMapping(
    new ConventionMappingSettings
    {
        ResolveTableSchema = (Type type) => 
        {
            if (type == typeof(MySpecialType))
            {
                return "MySpecialSchema";
            }

            return "dbo"; 
        }
    });

MicroLite 5.0 – Changes to Type Converters

In MicroLite 5.0, we have enhanced the Type Converters which we introduced in MicroLite 3.1.

The following method has been added to the interface:

object ConvertFromDbValue(IDataReader reader, int index, Type type);

This allows you to read the value from the IDataReader at the given index in the most efficient way (e.g. as an Int32 without the value being boxed).

From MicroLite 5.0, the full interface now looks like this:

ITypeConverter MicroLite 5.0

The ConvertFromDbValue(IDataReader, int, Type) is called when building an object from the results of a query, the ConvertFromDbValue(object, Type) method still exists but is only used when using ISession.Advanced.ExecuteScalar as there is no data reader used for that operation.

MicroLite 5.0 – Changes to Logging

In MicroLite 5.0, we have updated the logging API. The information in this post supersedes the information in the Using Logging in Custom Listeners post.

The extension methods which have been removed and the LogManager has been updated so that it will return an empty logger if none is configured. This means that as long as you call MicroLite.Logging.LogManager.GetCurrentClassLog(); you will be returned with an ILog instance.

The ILog interface has been updated with the following properties which allow you to check whether the log is configured at a given level before calling the corresponding log method. This can save on unnecessary calls to resource files and string formatting etc if the log isn’t capturing certain levels of data.

bool IsDebug { get; }
bool IsInfo { get; }
bool IsWarn { get; }
bool IsError { get; }
bool IsFatal { get; }

The ValidationListener in the Using Logging in Custom Listeners post would be updated as follows:

using MicroLite.Logging;

public class ValidationListener : MicroLite.Listeners.Listener
{
    private static ILog log = LogManager.GetCurrentClassLog();

    protected override BeforeInsert(object instance)
    {
        // This ensures that we only pay the cost of calling
        // .GetType() if we want to log the value anyway.
        if (log.IsDebug)
        {
            log.Debug(
                "Validating an {0} before insert",
                instance.GetType().Name);
        }

        ValidateObject(instance);
    }

    protected override BeforeUpdate(object instance)
    {
        // This ensures that we only pay the cost of calling
        // .GetType() if we want to log the value anyway.
        if (log.IsDebug)
        {
            log.Debug(
                "Validating an {0} before update",
                instance.GetType().Name);
        }

        ValidateObject(instance);
    }

    private void ValidateObject(object instance)
    {
        var warnings = Validator.GetWarnings(instance);
        var errors = Validator.GetErrors(instance);

        foreach (var warning in warnings)
        {
            if (log.IsWarn) { log.Warn(warning); }
        }

        foreach (var error in errors)
        {
            if (log.IsError) { log.Error(error); }
        }

        if (warnings.Count > 0 || errors.Count > 0)
        {
            throw new ValidationException(warnings, errors);
        }
    }
}

MicroLite 5.0 – Removal of methods from IListener

In MicroLite 5.0, the mutability of the SqlQuery object has been reduced. This change whilst helping improve the performance of MicroLite and reduce the memory footprint of the framework, does mean that the following methods on IListener can no longer be supported:

void BeforeDelete(object instance, SqlQuery sqlQuery);
void BeforeInsert(object instance, SqlQuery sqlQuery);
void BeforeUpdate(object instance, SqlQuery sqlQuery);

They were originally added in MicroLite 1.2.0 as an extensible point in the pipeline but the purpose of them was never that clear and they were never actually used within the framework itself.

Will this affect you at all? probably not.

  • If you have created a custom listener by inheriting from MicroLite.Listeners.Listener and have not overridden any of the methods mentioned then you won’t have a problem.
  • If you instead implemented MicroLite.Listeners.IListener yourself then if you didn’t actually perform any work in the methods mentioned then you can just delete them and you won’t have a problem.

If you think this change might affect you, move your code into the Before(object instance) method. If you were mutating the SqlQuery, let us know what you were doing and we will let you know the best way to handle it in 5.0.