Composing inter-dependant objects

Jul 8, 2013 at 7:09 AM
Hi there,

I'm trying to introduce MEF and nHibernate into a legacy windows forms application. I've currently got a factory which exports nHibernates' ISession interface and I'm trying to work out how to get a single instantiation injected into a form AND it's custom controls.

E.g. I have a custom search control that is used on many forms. I've added an ISession import as a property (as ImportingConstructor will break the windows forms designer). This custom search control is part of a form that also has a ISession on it's ImportingConstructor. How can I get the same instance of ISession that is used to compose the form, also into the custom control?

Or am I barking up the wrong tree with the direction I'm taking?
Coordinator
Jul 8, 2013 at 4:58 PM

hi mrsquish,

I am not very familiar with nhibernate, but the problem that you are running into would seem to be solvable by using the CompositionScopeDefinition class. At a high level . Composition Scope Definition allows you a mechanism to define scopes in which things are shared. Take a look at this article which talks about Composition Scope Definition and let us know if that works for you

http://blogs.msdn.com/b/bclteam/archive/2011/12/19/sharing-with-compositionscopedefinition-in-mef2-alok.aspx

cheers

Jul 8, 2013 at 11:13 PM
Hi alokshriram,

Thanks so much for the reply. Sorry I should have described the full situation a little better. I'm currently constrained to .Net 4.0 as my customers platforms include XP machines. So I don't think I can use MEF2?

Cheers.
Jul 8, 2013 at 11:17 PM
Hi alokshriram,

I've read up on the composition scope definition and it looks to be exactly what I'm after. Thank you for bringing it to my attention, now I just wish I could use it!
Coordinator
Jul 8, 2013 at 11:21 PM

J. Hopefully the article gets you started. Let me know if you run into issues.

thanks

-alok

Jul 8, 2013 at 11:38 PM
Hi Alok,

I'm pretty sure given my small amount of reading that I cannot use your solution as I'm constrained to .Net 4.0.
Coordinator
Jul 8, 2013 at 11:41 PM

Fair.. Sorry I missed your earlier comment about you using .Net 4.0

Jul 9, 2013 at 1:54 AM
For any of those that are interested, I ended up creating an interface IRequireSession which has the following declaration
    public interface IRequireSession
    {
        ISession Session { get; set; }
    }
And is implemented in a Form base class :
    public class DataForm : Form, IRequireSession
    {
        private ISession _session;

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Import()]
        public ISession Session
        {
            get { return _session; }
            set { 
                _session = value;
                SetSession(this.Controls);
            }
        }

        private void SetSession(Control.ControlCollection controls)
        {
            foreach (Control control in controls)
            {
                if (control is IRequireSession)
                    ((IRequireSession)control).Session = _session;
                SetSession(control.Controls);
            }
        }
    }
This means that I can derive my normal forms from DataForm and get the session passed through to any user controls that implement IRequireSession. Although, I've got a funny feeling that MEF doesn't support attributes on base classes. . I guess I'll find out soon enough.