Archive

Posts Tagged ‘Castle Windsor’

Creating MVC Controller Factories with Windsor

December 14, 2010 Leave a comment

You can setup dependency injection just by implementing the IControllerFactory interface or inheriting from DefaultControllerFactory. Default controller factory is preferred as it takes care of providing you more than just a controller name like Customer. Doing this manually is not great as you can see from the example below.

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Web.Mvc;
using System.Web.Routing;
using System.Linq;

namespace MVCSamples.Infrastructure
{
    public class WindsorControllerFactory : IControllerFactory
    {

        private IEnumerable<Type> _controllerTypes;

        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            BuildDefaultControllerTypes();
            return IoC.Resolve(GetTypeNameForController(controllerName)) as IController;
        }

        public void BuildDefaultControllerTypes()
        {
            if (_controllerTypes == null || !_controllerTypes.Any())
                _controllerTypes = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.Name.EndsWith("Controller")).ToList();
        }

        public string GetTypeNameForController(string controllername)
        {
            return _controllerTypes.First(x => x.Name == String.Format("{0}Controller", controllername)).FullName;
        }

        public void ReleaseController(IController controller)
        {
            var disposablecontroller = controller as IDisposable;
            if (disposablecontroller != null) disposablecontroller.Dispose();
            IoC.Release(controller);
        }
    }
}

The second implementation below is not so naive. The DefaultControllerFactory takes care of finding the controller type for you. Just override the GetControllerInstance Method.

using System;
using System.Web.Mvc;

namespace MVCSamples.Infrastructure
{
    public class WindsorControllerFactory : DefaultControllerFactory
    {

        protected override IController GetControllerInstance(Type controllerType)
        {
            return IoC.Resolve(controllerType) as IController;
        }

        public override void ReleaseController(IController controller)
        {
            var disposablecontroller = controller as IDisposable;
            if (disposablecontroller != null) disposablecontroller.Dispose();
            IoC.Release(controller);
        }
    }
}

Blair

StructureMap Manual Registration

October 26, 2010 Leave a comment

In an attempt to go and learn FubuMVC I decided to Learn the basics of StructureMap first. Being already fluent in Windsor this is a pain as now I am going to have to know how to use 2 containers.

I have put together a contrived example on how to manually register a concrete class against an interface and provided the basic code to do so.

I have other posts on IoC and containers if you want more information.

So heres the code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using StructureMap;

namespace StructureMapSamples
{

    interface ILogger
    {
        void Log(string message);
    }

    class Logger : ILogger
    {
        public void Log(string message)
        {
            Console.WriteLine(message);
        }
    }

    public static class BootStrapper
    {
        public static void WireUp()
        {
            ObjectFactory.Initialize(
                    x => x.For<ILogger>().Use<Logger>()
                );
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            BootStrapper.WireUp();

            ILogger logger = ObjectFactory.GetInstance<ILogger>();
            logger.Log("Hello World From StructureMap");

            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }

    }
}

As I get time between coding and learning Ruby I will add new posts with more advanced usages in the next few days.

Blair..

Web Forms MVP Presenter and Friends

April 25, 2010 Leave a comment

Hi all,
Its been a long time between posts. I have been flat out at work and way to busy. But I am currently building a MVP based Web Forms applications so I thought I would show the framework class involved and hopefully this helps you.

Here is the base view interface class.

    public interface IView
    {
        void DisplayMessage(string message);
        void DisplayError(string message);
        void Reload();
    }

I also have a couple of default base class which implement these methods as shown here.

    public static class FindControlUtility
    {
        public static Control FindControlRecursive(Control Root, string Id)
        {
            if (Root.ID == Id)
                return Root;

            foreach (Control Ctl in Root.Controls)
            {
                Control FoundCtl = FindControlRecursive(Ctl, Id);
                if (FoundCtl != null)
                    return FoundCtl;
            }

            return null;
        }
    }

    public abstract class WebFormsViewBase : Page, IView
    {

        public void DisplayMessage(string message)
        {

            Label messageLabel = FindControlUtility.FindControlRecursive(Master, "lblMessage") as Label;
           
            if(messageLabel == null)
                return;

            messageLabel.Visible = true;
            messageLabel.Font.Bold = true;
            messageLabel.ForeColor = Color.Green;
            messageLabel.Text = message;
        }

        public void DisplayError(string message)
        {
            Label messageLabel = FindControlUtility.FindControlRecursive(Master, "lblMessage") as Label; 

            if (messageLabel == null)
                return;

            messageLabel.Visible = true;
            messageLabel.Font.Bold = true;
            messageLabel.ForeColor = Color.Red;
            messageLabel.Text = message;

        }

        public void Reload()
        {
            Response.Redirect(Request.Url.AbsolutePath);
        }
    }

    public class UserControlViewBase : UserControl, IView
    {

        public void DisplayMessage(string message)
        {
            Label messageLabel = Page.FindControl("lblMessage") as Label;

            if (messageLabel == null)
                return;

            messageLabel.Font.Bold = true;
            messageLabel.ForeColor = Color.Green;
            messageLabel.Text = message;
        }

        public void DisplayError(string message)
        {
            Label messageLabel = Page.FindControl("lblMessage") as Label;

            if (messageLabel == null)
                return;

            messageLabel.Font.Bold = true;
            messageLabel.ForeColor = Color.Red;
            messageLabel.Text = message;

        }

        public void Reload()
        {
            Response.Redirect(Request.Url.AbsolutePath);
        }

    }

Moving on I also use a presenter base class as shown below.

public abstract class PresenterBase<T>
        where T : IView
    {
        public abstract T View { get; }
        public abstract void InitializeView();
    }

For automatic dependency injection with out heap of service locator class heres the presenter factory.

    public static class PresenterFactory
    {
        public static Presenter BuildPresenter<Presenter, View>(View view)
            where View : IView
            where Presenter : PresenterBase<View>
        {
            IoC container = new IoC();
            var resolvedPresenter = container.Resolve<Presenter>(view);
            return resolvedPresenter;
        }
    }

So putting it together here is how I wire up a presenter in my web form in the code behind.

InvoicePresenter _presenter = PresenterFactory.BuildPresenter<InvoicePresenter, IInvoiceView>(this);

Any questions post a comment more source can be post to further explain and help.

Blair…

Keep it Agile.

Castle Windsor – Registering Existing Object Instances

March 22, 2010 Leave a comment

Okay. Well we have not had a post on Castlw Windsor for a while so he we go. This is how to register an instance of an object you created in code against an interface. Basic you always get the object you passed in when you registered back. Sort of like a singleton. This can be useful if you have some extraordinary configuration to the object you need to do.

So here is come code showing it. You used the Instance Method to register your existing instance.

using System.Diagnostics;
using Castle.MicroKernel.Registration;
using Castle.Windsor;

namespace CastleWindsorDemo
{
    public class Customer
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public interface ICustomerRepository
    {
        void SaveCustomer(Customer customer);
        ISessionProvider Provider { get; }
    }

    public interface ISessionProvider
    {
        void StartSession();
        void CloseSession();
    }

    public class SessionProvider : ISessionProvider
    {
        public void StartSession()
        {
            
        }

        public void CloseSession()
        {
            
        }
    }

    public class CustomerRepository : ICustomerRepository
    {
        private readonly ISessionProvider provider;

        public CustomerRepository(ISessionProvider provider)
        {
            this.provider = provider;
        }

        public ISessionProvider Provider
        {
            get { return provider; }
        }

        public void SaveCustomer(Customer customer)
        {
            
        }
    }


    class Program
    {
        static void Main()
        {
            WindsorContainer container = new WindsorContainer();

            SessionProvider provider = new SessionProvider();
            container.Register(
                    Component.For<ISessionProvider>()
                             .Instance(provider)
                );

            container.Register(
                    Component.For<ICustomerRepository>()
                             .ImplementedBy<CustomerRepository>()
                             .LifeStyle
                             .Transient
                );

            var resolvedTypeA = container.Resolve<ICustomerRepository>();
            var resolvedTypeB = container.Resolve<ICustomerRepository>();

            Debug.Assert(ReferenceEquals(resolvedTypeA.Provider,resolvedTypeB.Provider));

        }
    }
}

You can also see how I am asserting they should be the same object.

Hope this helps..

Blair….

Categories: Development Tags: , , , ,

Castle Project Videos

March 10, 2010 Leave a comment

Hi all there is a new website that will show how do things in various castle project related packages. There also free.

The new site is castlecasts have a look seems like this will be really cool going forwards.

Blair..

Castle Windsor WCF Facility

March 5, 2010 Leave a comment

Firstly download this from the trunk, git://github.com/castleproject/Castle.Facilities.Wcf.git and build the sources. Once you have this installed then you need to get Castle Windsor to configure the facility as shown below

WindsorContainer container = new WindsorContainer();
            container.AddFacility<WcfFacility>();

            container.Register(
                    AllTypes.FromAssembly(Assembly.GetExecutingAssembly())
                            .Where(x => x.Name.Contains("Repository"))
                            .WithService
                            .FirstInterface()
                            .Configure(x => x.LifeStyle.Transient)
                );

            container.Register(
                    AllTypes.FromAssembly(Assembly.GetExecutingAssembly())
                            .Where(x => x.Name.Contains("Service"))
                            .WithService
                            .FirstInterface()
                            .Configure(x => x.LifeStyle.Transient)
                );

If your using WAS or IIS to host your services add the following line to the ServiceHost definition in the .svc file.

<%@ ServiceHost Language="C#" Debug="true" Service="Test.WebServices.Services.ProjectService" Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" CodeBehind="ProjectService.svc.cs" %>

Now your ready to rock and roll. You configure the rest of WCF as you would as per normal.

Blair…

Castle Windsor DependsOn vs Parameters

March 2, 2010 Leave a comment

They do the same thing but DependsOn is much more powerful. Parameters mirrors the XML configuration parameters section. All future development should use DependsOn.

Blair..

Categories: Development Tags: , , ,