Search code examples
c#.netmef

MEF prevent class from being manually instatiated


I wonder if I can somehow prevent class from being manually created? I want to make sure it is only imported.

[Export]
[PartCreationPolicy(CreationPolicy.Shared)]
public class TwoWayMessageHubService
{
    [ImportingConstructor]
    public TwoWayMessageHubService(ILoggerService loggerService)
    {
    }
}

So, I want to make sure this works:

[Import]
public TwoWayMessageHubService MHS {get; set;)

And make sure this doesn't:

var MHS = new TwoWayMessageHubService(logger);

Solution

  • In fact this is possible. Just have to apply [Import] attribute to your constructor's parameters and make your constructor private. I have made the following sample based on your code, it works and you can test it.

    First, the TwoMessageHubService with the changes I mentioned:

    [Export]
        [PartCreationPolicy(CreationPolicy.Shared)]
        public class TwoWayMessageHubService
        {
            [ImportingConstructor]
            private TwoWayMessageHubService([Import]ILogger logger) { }
        }
    

    Notice that the constructor is private

    Then a class that must be composed with an instance of TwoWayMessageHubService:

    public class Implementer
        {
            [Import]
            public TwoWayMessageHubService MHS { get; set; }
        }
    

    The Logger decorated with Export

       public interface ILogger { }
    
        [Export(typeof(ILogger))]
        public class Logger : ILogger { }
    

    And Main:

    var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
                var container = new CompositionContainer(catalog);
    
                var implementer = new Implementer();
                container.ComposeParts(implementer);
                //var IdoNotCompile = new TwoWayMessageHubService(new Logger());
    
                Console.ReadLine();
    

    If you uncomment the comment (lol) then you will notice that it does not compile.

    Hope this helps