I remember a while back some discussions about whether Repositories are a good or a bad thing. The case given as a bad example was one where the Repository had a large number of methods on it, whether Repositories are good or not was irrelevant, it was crap code :-)
Personally I DO use Repositories. Or, to be more accurate, I use A Repository.
public interface IDomainRepository
{
IEnumerable<T> AllInstances<T>();
}
To get a list of instances of a specific class I can obviously ask the DomainRepository for AllInstances<User> for example. This is just about as far as my Repository goes, so that in Unit Test code I can control which instances are “retrieved from the database” without having a database.
[TestMethod]
public void GetErrors_ReturnsError_ForDuplicateUserName()
{
var user1 = new User() { UserName = "A" };
var user2 = new User() { UserName = "A" };
var allUsers = new List<User> { user1, user2 };
var mockDomainRepository = MockRepository.GenerateMock<IDomainRepository>();
mockDomainRepository.Stub(x => x.AllInstances<User>()).Return(allUsers);
var validator = new UserValidator(mockDomainRepository);
Assert.IsTrue(validator.GetErrors(user1).Any(x => x.FieldName == "UserName" && x.ErrorMessage == "Already in use"));
}
I’ll write about filtering data soon.
Why is it that as soon as the word “government” is applied to a software project the cost multiplies massively and suddenly the project costs “millions”, runs over schedule, and usually doesn’t work when delivered.
A few months ago my wife and I saw a local lad break into a car and steal a wallet. A couple of weeks ago we were asked to go to the police station to do an identity parade. When we arrived we were told that unfortunately the “new” identity system had crashed and we wouldn’t be able to take part that day.
Today we went for another try. Again the police apologised and told us that the system was not working and we wouldn’t be able to take part in an identity parade. I was slightly annoyed by the incompetence of the IT people. I mean, why wasn’t the old system being used in parallel just in case of situations just like this? It’s not even as though they need to capture data and keep it in sync’, it’s just a video selection of 8 people + 1 suspect looking forward, left, then right.
Just as I had finished telling them how rubbish their new IT system is a police officer popped his head around the door with a big happy smile on his face and said “It’s okay, the file has arrived, we can continue!” After a little rejoicing I went and sat down at the computer in front of the most simple looking software application I think I have ever seen.
After sitting in front of it watching 9 blonde hair Caucasians looking forward, left, then right I was asked if I was able to identify the culprit. “No,” I replied, “the guy was Asian with black hair!”. The head office had obviously sent down the wrong set of videos for this case. Thankfully in this case the error was obvious, but what if they had sent down videos of 9 young Asian males? The error wouldn’t have been obvious and the guy would have got away with it!
Just a simple safeguard such as embedding the case number into the binary file and asking the officer to type in the expected case number for confirmation would have done the trick. Surely SOMEONE at some point must have considered an officer might be sent the wrong file, or open a file from the wrong email?
I can’t help but wonder how much they paid for that software. I could have easily written all of it within a month and it would have worked just fine. Unbelievable!
My server application works purely on a request/response pattern, like so
1: var query = new GetCustomerQuery(customerUniqueID);
2: var response =
3: AppServer.Execute<GetCustomerQuery, GetCustomerQueryResponse>(query);
What I wanted to avoid though was the possibility that the user (me writing the client app) would do something silly like the following code and use the wrong pair combination
1: var query = new GetCustomerQuery(customerUniqueID);
2: var response =
3: AppServer.Execute<GetCustomerQuery, GetEmployeeQueryResponse>(query);
Up until now I had the server interface defined like this, so that I can at least ensure the generic parameters are a Query and Response…
1: TResponse Execute<TRequest, TResponse>(TRequest request)
2: where TRequest : Request
3: where TResponse : Response;
But a very simple addition ensured that the response type specified is the right type for the request.
1: TResponse Execute<TRequest, TResponse>(TResponse response)
2: where TRequest : Request
3: where TResponse : Response, IResponseFor<TRequest>;
Then when I create my GetCustomerQueryResponse class I merely need to declare it like so
1: public class GetCustomerQueryResponse : Response,
2: IResponseFor<GetCustomerQuery>
3: {
4: //etc
5: }
Now the client code above won’t compile because GetEmployeeQueryResponse does not implement IResponseFor<GetCustomerQuery>.
The Enterprise Core Objects Persistence Mapper is a singleton which is used by all EcoSpace instances. It’s purpose is to load mapping information from the DB when your app starts and to cache it, improving performance.
I needed a connection per client, all running within a single application. This was a problem because once the PMP is created its connection string is tied to a single database. So I had to come up with a new PersistenceMapperDynamicSharer component. It is used on the EcoSpace to specify the PMapper type; additionally you can specify a connection string to use.
It works by dynamically creating a descendant class of your PersistenceMapperProvider at runtime, one for each connection string.
1: public class PersistenceMapperDynamicSharer : PersistenceMapperSharer
2: {
3: static ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
4: static Dictionary<string, PersistenceMapperProvider> MapperProviders = new Dictionary<string, PersistenceMapperProvider>();
5:
6: [Browsable(false)]
7: public string ConnectionString { get; set; }
8:
9: public override IPersistenceMapper GetPersistenceMapper(ITypeSystemService typeSystemService)
10: {
11: return GetPersistenceMapperProvider().GetPersistenceMapper(typeSystemService);
12: }
13:
14: public override void ReturnPersistenceMapper(IPersistenceMapper persistenceMapper)
15: {
16: GetPersistenceMapperProvider().ReturnPersistenceMapper(persistenceMapper);
17: }
18:
19: PersistenceMapperProvider GetPersistenceMapperProvider()
20: {
21: //No connection string = default mapper provider
22: if (string.IsNullOrEmpty(ConnectionString))
23: return PersistenceMapperProvider.GetInstance(MapperProviderType);
24:
25: PersistenceMapperProvider result;
26: Locker.EnterUpgradeableReadLock();
27: try
28: {
29: if (MapperProviders.TryGetValue(ConnectionString, out result))
30: return result;
31: Locker.EnterWriteLock();
32: try
33: {
34: var mapperType = CreateNewPersistenceMapperProviderType();
35: result = (PersistenceMapperProvider)Activator.CreateInstance(mapperType);
36: ((IDynamicallySharedPersistenceMapper)result).SetConnectionString(ConnectionString);
37: MapperProviders[ConnectionString] = result;
38: }
39: finally
40: {
41: Locker.ExitWriteLock();
42: }
43: }
44: finally
45: {
46: Locker.ExitUpgradeableReadLock();
47: }
48: return result;
49: }
50:
51: Type CreateNewPersistenceMapperProviderType()
52: {
53: string guid = Guid.NewGuid().ToString();
54: var assemblyName = new AssemblyName(guid);
55: var assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
56: assemblyName,
57: System.Reflection.Emit.AssemblyBuilderAccess.Run);
58: var moduleBuilder = assemblyBuilder.DefineDynamicModule(guid);
59: var typeBuilder = moduleBuilder.DefineType(
60: guid,
61: TypeAttributes.Class | TypeAttributes.Public,
62: MapperProviderType);
63: return typeBuilder.CreateType();
64: }
65: }
On my EcoSpace I have a method called ActivateWithConnectionString which I can use whenever I need to activate the EcoSpace connecting to a connection string OTHER than the default…
1: public void ActivateWithConnectionString(string connectionString)
2: {
3: persistenceMapperDynamicSharer1.ConnectionString = connectionString;
4: Active = true;
5: }
And on my PersistenceMapperProvider I need to implement IDynamicallySharedPersistenceMapper like so…
1: void IDynamicallySharedPersistenceMapper.SetConnectionString(string connectionString)
2: {
3: sqlConnection1.ConnectionString = connectionString;
4: }
Now I can benefit from the performance gains from the singleton-pattern implemented by PersistenceMapperProvider and connect to different databases.
My data-transfer-objects implement INotifyPropertyChanged, which was giving me a problem whenever I tried to serialise them over a Remoting session. If you try to add [NonSerialized] to the event you get an error informing you that you can only apply this attribute to fields, and not properties.
The solution is pretty simple, I think the .NET compiler should do this by default.
1: [NonSerialized]
2: PropertyChangedEventHandler propertyChanged;
3: public event PropertyChangedEventHandler PropertyChanged
4: {
5: add { propertyChanged += value; }
6: remove { propertyChanged -= value; }
7: }
I wanted to use a common base class for a set of UserControls in my WPF application, but when I changed the class’s ancestor in the code file and compiled I would get the error
“Partial declarations of must not specify different base classes”
This is because when you compile a WPF application Visual Studio generates a partial class in a code-behind file automatically, the base type specified is always “UserControl”. To solve this problem change your XAML from this
1: <UserControl
2: x:Class="MyApp.MyControl"
3: />
To this
1: <local:SomeBaseTypeYouWantToUse
2: x:Class="MyApp.MyControl"
3: xmlns:local="clr-namespace:NameSpace.To.Your.BaseClass"
4: />
I’m working on a new app which will have WPF as its user interface. With the slight nag in the back of my mind that someone might say “No, we want WinForms” (I hope not) I decided there should be as little code in the UI as possible so I opted for a view/controller approach where my controller will perform all of the logic and the view will only do “viewy” things.
One of the features of this app is that some of the views should appear as modal windows (such as a splash window during start-up) but others should appear as tabs in a client area so that the user can switch between different tasks. So I created a UserControl which data bound to a list of IView, there were two problems with this approach.
Firstly I wanted my IView implementers to be UserControls so that when I data bind to the List<IView> the content of the TabItem would show the correct control. The problem was that I needed the header of the TabItem to be data bound too…
1: <TabControl.ItemTemplate>
2: <DataTemplate>
3: <TextBlock Text="{Binding ViewTitle}"/>
4: </DataTemplate>
5: </TabControl.ItemTemplate>
So all I need is a string property on IView named ViewTitle and all would be well. Or so you would think! Data binding a TabControl to a list of objects which happen to be UserControl descendants doesn’t work very well, as a result the ItemTemplate was unable to read my property. Even if I converted it to a DependencyProperty it still didn’t work. It seems it is a problem with the way the WPF TabControl was written.
Secondly there was a problem when it came to wizard like views. When one of my tabs needs multiple steps how can I change the view? I can’t!
The solution was instead to data bind the TabControl to a list of controllers instead. Seeing as I already have IController for controllers which have modal views I went for List<IEmbeddedController> instead.
1: public interface IController : INotifyPropertyChanged
2: {
3: IView CurrentView { get; }
4: }
5:
6: public interface IEmbeddedController : IController
7: {
8: string ViewTitle { get; }
9: }
Now I can bind my TabItem.ItemTemplate to ViewTitle with no problem because it is not binding to a UserControl but a plain object instead. In addition the IEmbeddedController can set its CurrentView property at any point in order to show a different presentation to the user.
1: <TabControl.ContentTemplate>
2: <DataTemplate>
3: <ContentPresenter Content="{Binding CurrentView}" />
4: </DataTemplate>
5: </TabControl.ContentTemplate>
Now my tabbed views function correctly. I see a title on the tab item and the contents of the view. The next thing to address is how does the controller know which view to set CurrentView to? I do that using Unity dependency injection. So, for example, if I were to create a controller named “WizardTest” with two steps I would have the following items…
- IStep1View
- Step1Control (implements IStep1View)
- IStep2View
- Step2Control (implements IStep2View)
- IWizardTestController
- WizardTestController (implements IWizardTestController)
In the start-up phase of my application I would register which classes implement those interfaces…
1: static void RegisterWizardTestViewAndController(IUnityContainer container)
2: {
3: container.RegisterType
4: <
5: MyApp.Views.WizardTest.IWizardTestController,
6: MyApp.Views.WizardTest.WizardTestController
7: >(new TransientLifetimeManager());
8: container.RegisterType
9: <
10: MyApp.Views.WizardTest.Steps.IStep1View,
11: MyApp.Views.WizardTest.Steps.Step1
12: >(new TransientLifetimeManager());
13: container.RegisterType
14: <
15: MyApp.Views.WizardTest.Steps.IStep2View,
16: MyApp.Views.WizardTest.Steps.Step2
17: >(new TransientLifetimeManager());
18: }
When I need to show one of the states I write code something like this…
1: IStep1View Step1View;
2: private void SetStep1View()
3: {
4: if (Step1View == null)
5: {
6: Step1View = ViewFactory.CreateView<IStep1View>();
7: Step1View.Initialize(SomeModelObjectToEdit);
8: }
9: CurrentView = Step1View;
10: }
I can update the view on the screen simply by changing the CurrentView property. Let’s say that the Step1Control needs a NEXT button. This is easily achieved like so…
1: public interface IStep1View : IView
2: {
3: ICommand NextCommand { get; set; }
4: }
ICommand is an interface that WPF uses to bind UI actions to, for example in Step1Control I implement the property required by IStep1View and in the XAML I add a button like this…
1: <Button Content="Go to step 2" Command="{Binding CurrentView.NextCommand}"/>
CurrentView because (remember) the control is bound to the IEmbeddedController so we need the NextCommand of the CurrentView. When the user clicks this button it will execute the ICommand.Execute. This means that I don’t need a Button.Click event in the XAML, I don’t need to handle the event in the code-behind class, and I don’t need some kind of NextButtonClicked event on IStep1View - although I do instead need a NextCommand property instead, but all in all there’s less work…
1: IStep2View Step1View;
2: private void SetStep1View()
3: {
4: if (Step1View == null)
5: {
6: Step1View = ViewFactory.CreateView<IStep1View>();
7: Step1View.Initialize(SomeModelObjectToEdit);
8: Step1View.NextCommand = new ActionCommand(p => State = States.Step2);
9: }
10: CurrentView = Step1View;
11: }
ViewFactory is a very simple class which asks Unity to Resolve<> the type passed. This not only gives me simple construction but also injects any dependencies. ActionCommand is also a simple class which uses a lambda expression as its action to execute:
1: public class ActionCommand : ICommand
2: {
3: readonly Action<object> Action;
4: public event EventHandler CanExecuteChanged;
5:
6: public ActionCommand(Action<object> action)
7: {
8: Action = action;
9: Enabled = true;
10: }
11:
12: bool enabled;
13: public bool Enabled
14: {
15: get { return enabled; }
16: set
17: {
18: enabled = value;
19: var canExecuteChanged = CanExecuteChanged;
20: if (canExecuteChanged != null)
21: canExecuteChanged(this, EventArgs.Empty);
22: }
23: }
24:
25: public bool CanExecute(object parameter)
26: {
27: return Enabled;
28: }
29:
30: public void Execute(object parameter)
31: {
32: Action(parameter);
33: }
34: }
Clicking the button in the UserControl executes the NextCommand.Execute method, this is a lambda which sets State = States.Step2. The property “State” has a switch statement and calls SetStep1View, SetStep2View etc depending on the state that has been set.
Finally the management of the tabbed views, and how to show new views from other controllers. I did this with a service I called “IEmbeddedControllerPresenterController” because it is a controller which presents Embedded Controllers.
1: public interface IEmbeddedControllerPresenterController
2: {
3: void AddController(IEmbeddedController controller);
4: void RemoveController(IEmbeddedController controller);
5: void FocusController(IEmbeddedController controller);
6: UserControl UserControl { get; }
7: }
I’m going to change the “UserControl UserControl” property to “IView View'” very soon. But the idea is that this is registered in Unity with a ContainerControlledLifetimeManager (effectively a singleton). I can add and remove controllers from the list which my TabControl is bound to, and also specify which one should be focused.
Now when it comes to creating new views I use an IEmbeddedControllerRepository. It’s a repository because I don’t always create the embedded controller. When asking for a controller I pass a unique “InstanceID” which could be something simple like “NewCustomer” / “NewSupplier”, or when editing an instance of a user it could be the primary key of that user instance. This is to ensure that when you want a controller to edit “User A” and the interface already has a view editing that object the existing view will focus, if there is no view present for this object a new one will be created by calling a factory (simply delegates to Unity).
1: public interface IEmbeddedControllerRepository
2: {
3: TController GetController<TController>(string instanceID) where TController : IEmbeddedController;
4: void ReleaseController(string instanceID);
5: }
Two examples of using this might be…
1: var repository = EmbeddedUserRepository;
2:
3: //Example 1 - only create 1 new user at a time
4: repository.GetController<INewUserController>("NewUser");
5:
6: //Example 2 - edit any number of users, but never the same one twice
7: User user = .........;
8: var controller = repository.GetController<IEditUserController>(user.UniqueID);
9: controller.Initialize(user);
All of this is really just a slight variation of an approach I took for a wizard driven application I once wrote for the Pocket PC. The only difference is that the views are tabbed (whereas the PPC they were stacked and only 1 was visible at a time), and in this I am using Unity so that I can modularise the code a bit and potentially get some mocked objects in there via the interface definitions so that I can unit test more easily.
I’ve read (http://tech.groups.yahoo.com/group/domaindrivendesign/message/13738) that you should only have one controller per application. I simply don’t think this is true. While I do believe it is sometimes necessary to have a single controller responsible for multiple views I don’t think there are many apps which require only a single controller. E.g. if you are modelling a 3D scene and want to see a live preview of the scene in one window and sliders etc to control the camera angle you would use one controller, but if you are editing a customer, a supplier, and an employee you will need three different types of controller, and one instance of a controller per object you are editing in isolation.
I was looking for an outlook bar style control for WPF. I knew a guy named Divil from IRC had written some stuff so I decided to take a look. The first thing I looked at was Wunderbar, looked like what I wanted so I downloaded the trial.
I opened up the demo solution to see how it all works, but the problem is that the single window shows how it ALL works. It doesn’t demonstrate different concepts in different windows, it shows you how someone who already knows how to use the controls would create a complex user interface with them; that was no help.
So, I decided to click on the “User guide” link in the start menu to read what each of these controls do. There was only help for one of the controls, so how am I supposed to know what the other controls are for, or how they relate to each other etc?
Seeing as I knew the developer’s IRC nickname I decided to ask him if he had help files for those controls. He replied that they are so ridiculously easy to use that they don’t need any help; reminded me of “my code is so simple it doesn’t need tests”. I asked how I can find out what each control does and he told me “Don’t use them, they might format your hard drive”.
I think at this point I had seen enough. A demo app that isn’t focused, no content in the help files, and with an attitude like that before I part with any money what is the help going to be like once I’ve handed my cash over?
Time to look elsewhere…