Unity & Runnable Service

Apr 17, 2011 at 7:40 PM
Edited Apr 17, 2011 at 7:41 PM
I have interface:

    public interface IRunnableService
    {
        void Start();
        void Stop();
    }


I write small extension:



    public class RunnableExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {   
            Context.Strategies.Add(new RunnableBuilderStrategy(), UnityBuildStage.PreCreation);
        }
    }

    public class RunnableBuilderStrategy : BuilderStrategy
    {
        public override void PostBuildUp(IBuilderContext context)
        {
            base.PostBuildUp(context);
            if(context.Existing is IRunnableService) 
                Trace.WriteLine("PostBuildUp");
        }

        public override void PreTearDown(IBuilderContext context)
        {
            base.PreTearDown(context);
            if(context.Existing is IRunnableService) 
                Trace.WriteLine("PreTearDown");
        }

        public override void PostTearDown(IBuilderContext context)
        {
            base.PostTearDown(context);
            if(context.Existing is IRunnableService) 
                Trace.WriteLine("PostTearDown");
        }
    }


Use it:

 

m_container.AddNewExtension<RunnableExtension>()
                .RegisterType<IRunnableService, StateRefreshService>(
                    new ContainerControlledLifetimeManager());

m_container.Resolve<StateRefreshService>();

 

And in trace console: 

> PostBuildUp

How to use PreTearDown and PostTearDown events?

Or please tell other way or snippet to use RunnableService.

I need start some services, like Quartz.NET or other longlife services with start my program, and call Start() method.

And before disposing service (and container) call Stop() method.

Apr 17, 2011 at 9:06 PM

I create my lifetime manager, but RemoveValue never called:

    public class ServiceLifetimeManager : ContainerControlledLifetimeManager
    {
        public override void RemoveValue()
        {
            var obj = SynchronizedGetValue();
            
            if(obj == null) return;
            
            var shutdownMethod = obj.GetType().GetMethod("Shutdown");
            
            if(shutdownMethod == null) return;
            
            shutdownMethod.Invoke(obj, null);
        }

        public override void SetValue(object obj)
        {
            base.SetValue(obj);
            
            if(obj == null) return;

            var startMethod = obj.GetType().GetMethod("Start");
            
            if(startMethod == null) return;
            
            startMethod.Invoke(obj, null);
        }
    }

Apr 18, 2011 at 7:56 AM

There's no Unity code which calls the RemoveValue.  As mentioned by Chris Tavares in his blog, it is there for doing advanced extensions. 

As for the Pre and PostTearDown methods, they are only getting called if you explicitly call the TearDown method of the unity container.

Let me clarify what is your requirement.  Do you only need your Start method to be called upon resolving your objects from the container and call Stop method first on each object before they will be disposed?  If yes, then you can configure your Start method as an injection method by decorating it with the [InjectionMethod] attribute or do it through the config (refer to the container for the schema).  On the matter of calling Stop before the object gets disposed, why won't simply implementing the Dispose method such that it calls first the Stop method before actually disposing the object work for you?

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Apr 18, 2011 at 11:08 AM

Thank's for reply. I found solution after browse unity code.

I create extension for Quartz.NET:

    public class QuartzExtension : UnityContainerExtension, IDisposable
    {
        private IScheduler m_scheduler;

        protected override void Initialize()
        {
            Context.Container.RegisterType<IScheduler>(new ContainerControlledLifetimeManager(),
                           new InjectionFactory(f => f.Resolve<ISchedulerFactory>().GetScheduler()));

            m_scheduler = Container.Resolve<IScheduler>();
            m_scheduler.Start();
        }

        public void Dispose()
        {
            m_scheduler.Shutdown();
        }
    }

And use Disposable interface for my services, like tell You.

I like to try find one way solution for all cases.