Xabaril / Esquio

Esquio is a Feature Toggle Library for .NET Developers.
Apache License 2.0
428 stars 49 forks source link

How to add custom toggles to Esquio UI list of available toggles #187

Open luisflsmarques opened 3 years ago

luisflsmarques commented 3 years ago

Hi - how can I add a custom toggle, created following instructions on this link: doc. The doc explains how to create the toggle but it doesn't explain how to add it to the list of available toggles in Esquio UI.

I will have a look at the source code later to see if I can figure it out.

I thought that one way could be to configure manually the Toggles table in the DB schema by adding a new entry for each custom toggle but, from what I can see, that is not where the list of pre-configured available toggles comes from...

unaizorrilla commented 3 years ago

Hi @luisflsmarques

This is the code that load toggles on the UI

https://github.com/Xabaril/Esquio/blob/master/src/Esquio.UI.Host/Infrastructure/Services/DiscoverToggleTypesService.cs

Basically, load all assemblies with IToggle types defined! You can add assemblies to the execution context with your toogles or override IDiscoverToggleTypesService.cs to extend default assemblies to use.

  _typesCache = AppDomain.CurrentDomain
                    .GetAssemblies()
                    .Intersect(IntrospectionAssemblies)
                    .SelectMany(a => a.GetExportedTypes())
                    .Where(type => typeof(IToggle).IsAssignableFrom(type) && type.IsClass);

Remember use DesingType and DesignTypeParameter attributes to help the UI to understand the toggle and the parameters type to use.

    [DesignType(Description = "The value of the configured environment variable is in the list.", FriendlyName = "Environment Variable")]
    [DesignTypeParameter(ParameterName = EnvironmentVariable, ParameterType = EsquioConstants.STRING_PARAMETER_TYPE, ParameterDescription = "The environment variable name.")]
    [DesignTypeParameter(ParameterName = Values, ParameterType = EsquioConstants.SEMICOLON_LIST_PARAMETER_TYPE, ParameterDescription = "The values to activate this toggle separated by ';' character.")]
luisflsmarques commented 3 years ago

Hi - good morning. Thanks for the advice. I have looked into this over the weekend and I am still puzzled on how to make this work. Let me explain in more detail my use case: I have a custom toggle, which I have created following your guidance by implementing the IToggle interface and I also added the DesignType and DesignTypeParameter attributes. I also have a running container of the UI host on my local kubernetes cluster. My test web app, connects to this running UI host for its HTTP based store. So far so good. I have also called (not sure if this is required but saw it in one of your examples) the

.AddEsquio(setup =>
                {
                    ...
                    setup.RegisterTogglesFromAssemblyContaining<MyCustomToggle>();
                })

in the configure services method of my test web app.

Now the part I'm not quite sure is - what API am I going to call from the UI host running on Kubernetes to let that UI host know that there is a new custom toggle on my web app? You talk about adding the assembly of my web app where the custom toggle resides to the execution context, or override IDiscoverToggleTypesService.cs to extend default assemblies to use

Where do you mean I should do this? is this to be done on the configure services method? if so, is that meant to be done on the running UI host configure services? (if yes, does that mean that I need to shut it down and recompile / restart? - not what I intended to do) ...or do you mean i need to do this on my own web app configure services? if my own app - will this update the running UI host without needing a restart/redeploy of that UI host?. If you could just elaborate more with an example that would be greatly appreciated. Thank you. Ideally I would like to let the UI host know of the additional custom toggle without needing to redeploy the Esquio UI Host or restart it.

unaizorrilla commented 3 years ago

Hi @luisflsmarques

The method RegisterTogglesFromAssemblyContaining is used to register custom toggles on Client, not on the UI, both are necessary!

You need to override the IDiscoverToggleTypeService on the UI and register your new service, unfortunately is not a way to do that without create your custom image, but we are happy to get a PR on this or open a discussion about the this feature design.

Hope this help!

luisflsmarques commented 3 years ago

Ok I get it, I think... :-) - so I would need to create my own image of the UI to get it updated and running with the knowledge of the new toggle. So out of the box, I would have to 1) Put all custom toggles in some sort of class library which would be shared between my web app and the UI host 2) recompile the UI and create a new image 3) redeploy the new UI host image on Kubernetes and then finally run my new web app which makes use of those same custom toggles. It would definitely make a lot of sense to have an API on the UI host where we could call it to "feed it" the new custom toggles - that would make this long term sustainable in an enterprise environment. Can you share the dockerfile for the latest image (I believe that is 5.0?). Does that Dockerfile for 5.0 build the so called Esquio.UI.Client or the Esquio.UI.Host web app or both?

unaizorrilla commented 3 years ago

Hi @luisflsmarques

Yeap, I'm thinking on reduce the dependencies on libraries for the UI to use custom toggles, but, i need some time to implement this!

Dockerfile is here!

https://github.com/Xabaril/Esquio/blob/master/build/UIDockerfile

unaizorrilla commented 3 years ago

Hi @luisflsmarques

We are talking about this feature and our approach for this feature is:

this drop the issue of create different images for your custom toggles and I think improve the experience!

What do you think on this design?

luisflsmarques commented 3 years ago

anything that will remove the need to create a new image will definitely be a strong move towards making Esquio an even greater solution. A few questions if I may: 1) When you say a MapEsquio similar endpoint on the client application - do you mean - for example my test web app which is using Esquio to manage features?. So in the test app, when it imports Esquio libraries and configures the Esquio endpoints (endpoints.MapEsquioCustomToggles(pattern: "esquiocustomtoggles")), it will gain a new endpoint "automagically" (I assume you will provide the implementation of this endpoint like you did for MapEsquio)?.

2) Do you mean to say that the Esquio UI will then have, for each product, an endpoint configuration textbox on the UI in which we can type the URL and have the Esquio UI host then call the test app /esquiocustomtoggles when we click "load custom toggles", which will then result in the Esquio UI being updated with our custom toggles without even needing a restart?!

If the answers to these are all yes - then AWESOME! when can we expect them ? :-)

unaizorrilla commented 3 years ago

Hi @luisflsmarques

1 Yes, that is the idea and I start the work on features/expose-custom-toggle-data-from-app 2 Yes

:-), hope this help to decide to use this product! I try finish these feature soon!