Removing concrete instance from IOC

Member since: 2007

Hi, need some help,

How do i remove this internal class when it is registred like this in EPiServer.Cms.Shell.UI.dll

  [ServiceConfiguration(typeof (INotificationFormatter))]
  internal class ApprovalHtmlEmailFormatter

There is no room for two, and i'd like to use mine... =) Since it is internal it is not visible in my code...

Any help appreciated.

-Regards

#182085 Sep 08, 2017 17:01
  • Member since: 2011

    Add interceptor around this and "silence" original one. Had exactly the same issue with epi forms view external resource provider.

    #182090 Sep 08, 2017 17:52
  • Member since: 2011

    You can always eject all current registered instances, then register yours. 

    #182092 Sep 08, 2017 19:18
  • Member since: 2011

    it might work in cases when you really want to dominate. there are also cases when you need to suppress that one particular instance (shut it off) but leave rest as-is. and in most cases you don't know who else is there ;)

    #182093 Sep 08, 2017 20:33
  • Member since: 2011

    Yes, but Gosso wanted to show who is the boss (tip: he is)

    #182099 Sep 09, 2017 1:23
  • Member since: 2007

    yes, thanks, 

    context.StructureMap().Model.EjectAndRemove(typeof(INotificationFormatter));
    
    //addin mine
    context.StructureMap().Configure(ce =>
    {
    ce.For<INotificationFormatter>().Singleton().Use<CustomApprovalHtmlEmailFormatter>();
    });

    works, but i will look for finding the explicit concrete class, so i don't remove all other INoficationFormatter out there.

    Bellow is not working though

     context.StructureMap().Model.EjectAndRemovePluginTypes(type => type.Namespace != null && 
                type.Namespace.Equals("EPiServer.Cms.Shell.UI.Approvals.Notifications") &&
                               type.Name.Equals("ApprovalHtmlEmailFormatter"));

    #182101 Sep 09, 2017 10:10
  • Member since: 2011

    Aaaand still don't you want to try intercept? ;))

    #182102 Sep 09, 2017 11:44
  • Member since: 2007

    having no luck here 

    Tried Intercept...

                context.StructureMap().Configure(container =>
                {
                    container.For<INotificationFormatter>().DecorateAllWith(instance =>
                        proxyGenerator.CreateInterfaceProxyWithTargetInterface(instance, new RemoveDefaultApprovalFormatterInterceptor()));
                });

    But it is NOT hooking up on specific class, just other INotificationFormatters

    DEFAULT IoC PuginType and ConcreteType is "EPiServer.Cms.Shell.UI.Approvals.Notifications.ApprovalHtmlEmailFormatter,EPiServer.Cms.Shell.UI, Version=10.9.1.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7" SCOPE: StructureMap.Pipeline.SingletonLifecycle

    When i remove the type with for example context.StructureMap().Model.EjectAndRemove(t.PluginType); the SCOPE changes to Transient (meaning it reinitiated on every call)

    Removing permanentaly seems not possible?...

    Any Idea how to intercept without having the concrete class since it is internal?

    hmm

    #182128 Sep 11, 2017 14:32
  • Member since: 2011

    you can get to work this with code below:

    [InitializableModule]
    [ModuleDependency(typeof(DependencyResolverInitialization))]
    public class EPiServerFormsConfigurationModule : IConfigurableModule
    {
        public void Initialize(InitializationEngine context) { }
        public void Uninitialize(InitializationEngine context) { }
        public void ConfigureContainer(ServiceConfigurationContext context)
        {
            context.Services.Intercept<INotificationFormatter>((locator, service) => new FixedApprovalHtmlEmailFormatter(service));
        }
    }
    
    public class FixedApprovalHtmlEmailFormatter : INotificationFormatter
    {
        private readonly INotificationFormatter _inner;
        public FixedApprovalHtmlEmailFormatter(INotificationFormatter inner)
        {
            _inner = inner;
        }
        
        public Task<IEnumerable<FormatterNotificationMessage>> FormatMessagesAsync(IEnumerable<FormatterNotificationMessage> notifications,
                                                                                   string recipient,
                                                                                   NotificationFormat format,
                                                                                   string channelName)
        {
            return _inner.FormatMessagesAsync(notifications, recipient, format, channelName);
        }
        public IEnumerable<string> SupportedChannelNames => new[] { "test" };
    }

    in ideal case I would use `locator.GetInstance<INotificationFormatter>()` in `Intercept()` method, but then you will get circular dependencies and blow up from structuremap.

    #182134 Sep 11, 2017 15:29
  • Member since: 2011

    and forgot to mention that `DependencyResolverInitialization` module is my own module where I set dependency resolvers to Mvc and WebApi (created out of epi's structuremap container), but I guess you don't need explicitly chain to that phase of the initialization pipeline.

    #182135 Sep 11, 2017 15:31
  • Member since: 2007

    thx, valdis, your code illustrates it and works in "INotificationFormatter", but no luck because when i run context.StructureMap().WhatDoIHave(); the object "ApprovalHtmlEmailFormatter" is not attached to "INotificationFormatter". It is attached to it self concret class ApprovalHtmlEmailFormatter. Even if it is an INotificationFormatter.

    So the question how do i "attach" to ApprovalHtmlEmailFormatter when it is not accessable...

    #182140 Sep 11, 2017 16:17
First   1 2   Last