»
S
I
D
E
B
A
R
«
Too Easy: Instant Data Access Layer with SubSonic and SQLite
Oct 20th, 2009 by Josh Rivers

It’s frightening just how much pain I have in starting a new application project. Creating an SQL database, deploying a schema, building an ORM access layer, and putting all the pieces into source control to deploy, version, update that database, both on the development SQL Express, and the production SQL Server instances—it takes time. It takes work. The only thing worse than putting in all that effort is doing the cowboy bit with the tools and NOT doing it. Then you have various unsynchronized, untestable, messy databases and deployed versions of code. Oook!

SubSonic 3.0 introduced the SimpleRepository and Auto-Migrations. These Ruby-on-Rails-inspired features, when coupled with SQLite can make your DAL-creation tasks just disappear. Let’s give it a try!

  1. Download and install System.Data.SQLite. This distribution of SQLite is a single mixed-mode dll that contains a recent SQLite build as well as ADO.NET bindings for the database. Also in the package is a linq provider, and Visual Studio Server Explorer support. image
  2. Download SubSonic 3. There’s all sorts of great stuff in this download. Three different data access models. Modifiable templates. Examples. But you only need the single dll from the binaries folder. Toss the rest in a drawer and look at it later.
  3. Add some the references to your project.
    image 
  4. Create a RepositoryFactory class:
    public class SubsonicRepositoryFactory{    public static SimpleRepository GetRepository()    {        var provider = SubSonic.DataProviders.ProviderFactory.GetProvider("Data Source=|DataDirectory|my.db", "System.Data.SQLite");        var repository = new SimpleRepository(provider, SimpleRepositoryOptions.RunMigrations);        return repository;    }}

    This isn’t strictly necessary…but I hate putting my connection strings in all those angle brackets, and prefer to detect my production/test/development environments in code rather than in XML.

  5. You’re done! Make your own POCOs and use commands like SubsonicRepositoryFactory.GetRepository().Add(myObject);
  6. Go home. You’ve worked hard. Relax.

This is good stuff, and it certainly can take some of the pressure off of starting up a new project. With data access and persistence just ‘done’, you can get to logic and value quicker. And you always have the option of upgrading to a more ‘serious’ data layer if you need it later. I’m really curious if SubSonic/SQLite can provide a reasonably performant small-to-midsize backing store to a web service application server. If your applications and various UIs all access their data through the web services, who cares what the persistence storage is, and until that back end is doing enough work to require multiple servers, how much trouble can you get into by caching your objects in memory and persisting them to disk using SQLite?

It’s also worth noting that SimpleRepository doesn’t have any wiring for child collections yet. Rob has said on StackOverflow that he intends to do some work on that, but it’s not in there yet. However, it shouldn’t be too hard to drop some convenience methods on your POCOs (extension methods if you’re worried about polluting your classes) to emit Lists or IEnumerables of linked collections.

Using StructureMap to Build Your MVC Controllers
Jul 26th, 2009 by Josh Rivers

The simplest things seem to be the hardest to find the up-to-date documentation on.
Adding a ControllerFactory to MVC is very simple, and making it work with StructureMap
is pretty quick, but do you really want to write any of that code? Of course not.
Somebody else can do it.

The MVC Contrib project has built all of the code you need to make a number of the
popular IoC frameworks work in your project. Unfortunately IoC frameworks update a
lot, and the MvcContrib project was finding it pretty hard to keep up with the latest
versions when they compiled their builds. So that code is deprecated. Don’t use it.

Here’s how you add StructureMap to build controllers in your MVC project:

Create a StructureMapControllerFactory Class

using System;
using System.Web.Mvc;
using System.Web.Routing;
using StructureMap;

namespace MvcContrib.StructureMap
{
public class StructureMapControllerFactory
: DefaultControllerFactory
{
public override IController
CreateController(RequestContext context, string controllerName)
{
Type controllerType = base.GetControllerType(controllerName);
return ObjectFactory.GetInstance(controllerType) as IController;
}
}
}

Add a Method to Global.asax

private void ConfigureIoC()
{
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
}

Add a call to that method in Application_Start

ConfigureIoC();

….and now we can go out for steak and exotic dancers. Your controllers will have their
dependencies injected all nice and purty.

Incorporating Growl For Windows into my Application
Jun 23rd, 2009 by Josh Rivers

I’m a big believer in re-use. Code I don’t aihave to write is code I don’t have to
debug or maintain. When I discovered that I’d really like some notification
toast
in my Windows Forms enterprise application, I immediately started looking
for libraries.

The definitive toast solution for Mac OS is Growl.
Growl is a separate application/control panel that runs on your system and manages
notifications from all subscribing services on your system. No more overlapping toast.
It also provides a lot of filtering, control, and plugin-based extensibility. Did
you want your ‘new mail’ notifications to show up on your cell phone as SMS rather
than on your desktop? Just do it. Want the toilet to flush when the build fails? Get
an Arduino and script it up!

Needless to say I was really chuffed to find the Growl
for Windows
project. Their application is still in beta, but the developers are
very responsive, and they are checking code fixes in within hours of getting bug reports
when they can. GfW can provide you notifications for your GMail, Outlook, Visual Studio
Builds, and the current song playing in Pandora.

Installing Growl With My Application

My application installs with NSIS. Adding
automatic installation of the Growl client to my installer was very quick. I grabbed
the .msi file from the Growl download, and put it within my build tree. Then I added
the following snippet to my NSIS script:

Section "Growl
Install" SEC01
File "Growl\Windows Deployment.msi"

ExecWait 'MSIEXEC.EXE /I "$INSTDIR\Windows Deployment.msi"
/QB- ALLUSERS=1'

SectionEnd

That’s it for the install. However, I wanted it to uninstall cleanly as well, so I
added the following line to the uninstall section:

ExecWait 'MSIEXEC.EXE
/x "$INSTDIR\Windows Deployment.msi" /qn'

Two caveats:

  1. You may not want to uninstall Growl automatically for the user, in case they had installed
    it on their own and want to uninstall your app, but keep Growl. This isn’t an issue
    in my business deployment, but it may be one for a public application.
  2. There may be some issues with UAC installs, and I haven’t tested this yet. I think
    I can just run my NSIS exe ‘As Administrator’ and have it work, but there may be issues
    with msiexec and UAC.

Code to Send Notifications

First things first, lets establish some interfaces to program to, that way we can
swap out implementations for testing and if our needs change.

public interface INotificationMessage
{
string MessageType { get; }
string MessageDescription { get; }
string MessageId { get; }
string MessageText { get; set; }
Image MessageIcon { get; }
Action AcceptMessageCallback { get; set; }
Action DeclineMessageCallback { get; set; }
}
public interface INotificationSender
{
void SendMessage(INotificationMessage message);
}

Next, we’ll implement a specific Notification Message type. Each Notification Message
type can be instantiated of a specific type so that it’s very easy to add new types
as well as very easy to use them. Each type can have an icon of it’s own.

public class ApplicationErrorNotificationMessage
: INotificationMessage
{
public string MessageType
{ get; private set; }
public string MessageDescription
{ get; private set; }
public string MessageId
{ get; private set; }
public string MessageText
{ get; set; }
public Image MessageIcon { get; private set;
}
public Action AcceptMessageCallback { get; set;
}
public Action DeclineMessageCallback { get; set;
}

public ApplicationErrorNotificationMessage()
{
this.MessageType = "APPLICATION_ERROR";
this.MessageDescription = "Application
Error";
this.MessageId = Guid.NewGuid().ToString();
this.MessageIcon = Application.Properties.Resources.AppIcon;
}
}

It appears that growl caches the message icons, so you might need to restart the Growl
process if you go changing your Notification icons.

Finally we have our implementation of INotificationSender which registers with Growl,
ensures that it is installed, and ensures that it is running.

public class GrowlNotificationSender
: INotificationSender
{
private GrowlConnector connector;
private Image applicationIcon;
private string applicationName;
private INotificationMessage[] messageTypes;
private Dictionary<string,
INotificationMessage> sentMessages;

public GrowlNotificationSender(INotificationMessage[]
messageTypes,
Image applicationIcon,
string applicationName)
{
this.connector = new GrowlConnector();
this.messageTypes = messageTypes;
this.applicationIcon = applicationIcon;
this.applicationName = applicationName;
this.sentMessages = new Dictionary<string,
INotificationMessage>();

EnsureGrowlIsRunning();
RegisterWithGrowl();
}

private void RegisterWithGrowl()
{
Application thisApplication = new Application(applicationName);
thisApplication.Icon = applicationIcon;
List<NotificationType> notificationTypes = new List<NotificationType>();
foreach (var messageType in messageTypes)
{
NotificationType notificationType =
new NotificationType(messageType.MessageType,
messageType.MessageDescription);
notificationType.Icon = messageType.MessageIcon;
notificationTypes.Add(notificationType);
}
this.connector.Register(thisApplication, notificationTypes.ToArray());
this.connector.NotificationCallback += new GrowlConnector.CallbackEventHandler(connector_NotificationCallback);
this.connector.EncryptionAlgorithm = Cryptography.SymmetricAlgorithmType.PlainText;
}

public void EnsureGrowlIsRunning()
{
Process[] processlist = Process.GetProcesses();
foreach (Process theprocess in processlist)
{
if (theprocess.ProcessName.Equals("Growl"))
{ return; }
}

Detector detector = new Growl.CoreLibrary.Detector();
if (detector.IsAvailable)
{
System.Diagnostics.Process.Start(detector.InstallationFolder + @"\Growl.exe");
Thread.Sleep(1000);
return;
}
else

{
throw new FileNotFoundException("Growl
not installed?");
}
}

void connector_NotificationCallback(Response response,
CallbackData callbackData)
{
if (sentMessages[callbackData.Data] != null)
{
if (callbackData.Result == CallbackResult.CLICK)
{
if (sentMessages[callbackData.Data].AcceptMessageCallback
!= null)
{
sentMessages[callbackData.Data].AcceptMessageCallback.Invoke();
}
}
else

{
if (sentMessages[callbackData.Data].DeclineMessageCallback
!= null)
{
sentMessages[callbackData.Data].DeclineMessageCallback.Invoke();
}
}
sentMessages.Remove(callbackData.Data);
}
}

public void SendMessage(INotificationMessage
message)
{
this.sentMessages.Add(message.MessageId, message);

CallbackContext callbackContext = new CallbackContext();
callbackContext.Data = message.MessageId;
callbackContext.Type = message.MessageType;

Notification notification = new Notification(this.applicationName,
message.MessageType,
message.MessageId,
message.MessageDescription,
message.MessageText);

EnsureGrowlIsRunning();
this.connector.Notify(notification, callbackContext);
}
}

This implementation keeps track of sent messages, and executes callbacks on them depending
on the user’s response. If you don’t want to use one of the callbacks, just leave
it undefined.

I haven’t found a way to get Growl to send the CLOSE message rather than the TIMEOUT,
but that’s ok, since I treat them the same.

Using The Code

You’d probably want to wire this up with your IOC container, but here’s a manual usage.

INotificationSender sender = new GrowlNotificationSender(
new[] { new ApplicationErrorNotificationMessage()
},
Moneta.Properties.Resources.Crystal_128_package_network,
"My Application"

);
Thread.Sleep(1000);
ApplicationErrorNotificationMessage message = new ApplicationErrorNotificationMessage
{
MessageText = "Hi There",
AcceptMessageCallback = () => MessageBox.Show("You
clicked"),
DeclineMessageCallback = () => MessageBox.Show("Pay
Attention!")
};
sender.SendMessage(message);

It’s worth noting that the first registration of your app may take a moment for Growl
to process, and that’s why I have the Sleep() in there. If your app doesn’t intend
to immediately send a message after it’s first registration, that’s unnecessary.

Resources

Windows Forms Eventing: Thread Synchronization
Jun 23rd, 2009 by Josh Rivers

So last time, we created this great event aggregator for our Windows Forms applications.
Instead of having the code that sends messages directly connected to the code that
receives messages, everybody just knows about the event aggregator. This works the
same way you don’t need turn-by-turn directions to Fox News Headquarters to mail them
a box of dirty diapers.

The catch is that the code so far only works if all the senders and receivers are
on the same thread. If they are on different threads, who knows what may happen? (Not
me. I failed out of Home-Ec. I don’t even know how you turn cotton flowers into threads,
let alone how to make them fit together.)

There is a simple fix, however. The .NET 2.0 SynchronizationContext is used by Windows
Forms and can provide an easy-to-use central choke point to manage all of our thread-to-thread
communications.

Remember Your Singleton

When I was cutting and pasting together this code from the Intarnets, one big problem
I had was forgetting to initialize my singleton correctly. It’s really important
that you initialize your singleton EventAggregator from SynchronizationContext.Current
in the Windows Forms Thread. Setting the thing up right in StructureMap or
your IOC Container of choice works just great. Just make sure it gets done. (My mistake
also involved letting StructureMap use “new SynchronizationContext()” in initializing
my singleton rather than “SynchronizationContext.Current”.) Get it right the first
time and you won’t have to do multithread debugging.

EventAggregator Class

public class EventAggregator
: IEventAggregator
{
private readonly SynchronizationContext
_context;
private readonly List<object>
_listeners = new List<object>();
private readonly object _locker
= new object();

public EventAggregator(SynchronizationContext
context)
{
_context = context;
}

#region IEventAggregator Members
public void SendMessage<T>(T
message)
{
sendAction(() => all().CallOnEach<IListener<T>>(x => { x.Handle(message);
}));
}

public void AddListener(object listener)
{
withinLock(() =>
{
if (_listeners.Contains(listener)) return;
_listeners.Add(listener);
});
}

public void RemoveListener(object listener)
{
withinLock(() => _listeners.Remove(listener));
}
#endregion

private object[]
all()
{
lock (_locker)
{
return _listeners.ToArray();
}
}

private void withinLock(Action
action)
{
lock (_locker)
{
action();
}
}

protected virtual void sendAction(Action
action)
{
_context.Send(state => { action(); }, null);
}
}

Notice the locking. Notice the creation of a copy of the _listeners list into an array
for Thread Safety. Most importantly, notice the use of _context.Send(). A few minor
changes…but now the whole class is thread safe, and synchronous between threads. Hooray!

Next Time

I’ve still got lots to cover on this subject. How do you use the eventing in your
application architecture. Using Weak References to protect your event system from
memory leaks. Sending events to a specific target or set of targets. I’m going to
be working on some other projects for a bit, so it may be a while before I write those
posts, but hopefully what we’ve covered so far is useful on its own until then.

Resources

»  Substance: WordPress   »  Style: Ahren Ahimsa