开发者

Spring.NET & Immediacy CMS

Is 开发者_运维问答there any way to inject dependencies into an Immediacy CMS control using Spring.NET, ideally without having to use to ContextRegistry when initialising the control?


As an ex Immediacy employee i used to see this sort of problem all the time.

Think of immediacy as being a standard .net web app that sits on top of the framework. They have simply extended the base classes for things like the Page class and added some globally useful objects.

Immediacy does have its own base classes for controls ect but there's nothing stopping you creating your own controls based on the standard .net classes.

One trick I have seen where you need to do something specific that may break an immediacy function is to create a child application then call up pages from it within a custom control that you add to the main app.

This way your child app can do what it likes without breaking anything and the parent immediacy app and simply reads a stream from that app.

in its simplest form the trick is to simply create a control that does one thing ...

WebClient wc = new WebClient();
this.Controls.Add(Page.ParseControl( wc.DownloadString("/childapp/yourcustomthing.aspx") ));

The cleanest other way to do this is to implement the required child component as an ashx handler from what i've seen.

The only issue that may bring up is that you lose the immediacy framework of objects in your child app, but you could easily pass in some key information via querystrings then build your own "depency cache" that contains the stuff you need.

It's not an ideal I know but immediacy does have a habit of making life difficult when you need to do anything above and beyond dropping in lists / similar plugins to pages or templates.


I'm going to answer this one with a solution I've used for over a year with Immediacy 6.x. In theory, this should work with Alterian CMC 7.x (Immediacy's successor) with some modification.

The issue here is that Immediacy already has a handler defined in web.config that deals with all aspx pages. However, I've found this can be replaced with an entry for Spring.NET's PageHandlerFactory in web.config, as per most webforms apps!

However, some tweaking is still needed since out of the box, there are still issues with the previewer. The process for getting Spring.NET to play nicely with an Immediacy Control is:

  1. Add the usual entries to web.config for Spring.NET as outlined in the documentation. In this case I've got my object definitions in Spring.config.

  2. Create the following abstract base class that will deal with all of the Dependency Injection work:

    SpringImmediacyControl.cs

    public abstract class SpringImmediacyControl : ImmediacyControl, ISupportsWebDependencyInjection
    {
        // You can do the same thing for other control classes, like LiteralControl
    
        #region ISupportsWebDependencyInjection Members
    
        public IApplicationContext DefaultApplicationContext
        {
            get;
            set;
        }
    
        #endregion
    
        protected override void OnInit(EventArgs e)
        {
            // Required for page preview, which is executed using Immediacy's page preview handler
    
            if (DefaultApplicationContext == null)
            {
                DefaultApplicationContext = ContextRegistry.GetContext() as WebApplicationContext;
                DefaultApplicationContext.ConfigureObject(this, this.GetType().FullName);
            }
    
            base.OnInit(e);
        }
    
        protected override void AddedControl(Control control, int index)
        {
            this.EnableViewState = false;
    
            // Handle DI for children ourselves - defaults to a call to InjectDependenciesRecursive
    
            if (DefaultApplicationContext != null)
                WebDependencyInjectionUtils.InjectDependenciesRecursive(DefaultApplicationContext, control);
    
            base.AddedControl(control, index);
        }
    }
    

    This is similar to the code for server side controls over on the Spring.NET documentation. However, the extra OnInit & null checking code is needed is because the previewer renders the control under Immediacy's own previewer HTTP Handler. This means a manual call to Spring.NET's context registry is needed to inject dependencies.

  3. For any control with which you wish to use with Spring.NET's Inversion of Control container, add the relelvant entry to Spring.config, for example:

    SampleControl.cs

    public class SampleControl : SpringImmediacyControl, INamingContainer
    {
        public string Text
        {
            get;
            set;
        }
    
        protected string InjectedText
        {
            get;
            set;
        }
    
        public SampleControl()
            : base()
        {
            Text = "Hello world";
        }
    
        protected override void RenderContents(HtmlTextWriter output)
        {
            output.Write(string.Format("{0} {1}", Text, InjectedText));
        }
    }
    

    Spring.config

    <objects xmlns="http://www.springframework.net">
        <object type="MyProject.SampleControl, MyAssembly" abstract="true">
            <property name="InjectedText" value="from Spring.NET" />
        </object>
    </objects>
    
  4. Provided everything's done correctly, you will have the control writing out "Hello world from Spring.NET!" when used in a page.

All of the code I've used can be downloaded & forked from here.

As an aside, the process is similar if you wish to create Spring.NET compatible subclasses of ButtonPluginConfig, except these subclasses are always executed under Immediacy's own HTTP Handler for control configuration, & so calling Spring.NET's context registry is always required. I've included an abstract class derived from ButtonPluginConfig in the gist above as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜