Giter Club home page Giter Club logo

Comments (10)

aloneguid avatar aloneguid commented on July 17, 2024

I don't see a reason why not, just need to write a couple of tests to check that properties are OK, config.net uses reflection to find source objects.

The reason it's not there is simply because we never had such problem. I would normally pass values to constructors and won't have any dependency on configuration outside of startup code. That also makes classes unit-testable with no fancy dependencies. However I can understand why interfaces on top might be really useful.

Are you happy to create a PR for this?

from config.

jsobell avatar jsobell commented on July 17, 2024

I took a look at this, and there is a tricky issue that has me slightly stumped.
Because each field is an Option, reflection is used to iterate over the fields, retrieve the value, and part of the initialisation is to set _parent to this.
Now if we use properties, the call to GetValue returns a proxy referring to what appears to be a different instance of the Option, so setting _parent does so on a new instance and the change is never written to the original property.
I'll have another look at it shortly, but it's a very odd issue, almost as though you need to gain a reference to the underlying backing variable directly.

from config.

jsobell avatar jsobell commented on July 17, 2024

OK, my stupidity.
Option<string> myThing => new Option<string>()
is not the same as
Option<string> myThing { get; } = new Option<string>()
even though it behaves in a similar way.

I've created a branch at https://github.com/jsobell/config/tree/property-based that uses properties, but I'm not sure if or how this might be used. Interfaces on configuration objects are a common requirements, as most IOC code patterns will expect injection of a singleton configuration object, and this should to be referred to by its interface, but there is the issue of a breaking change.
I'll let you decide what's the best approach :)

from config.

aloneguid avatar aloneguid commented on July 17, 2024

I'm working on a prototype of v4 which should allow doing something like this:

   public interface IServerSettings
   {
      string Address { get; set; }

      [Option(DefaultValue = "nokey")]
      string Key { get; set; }
   }

         IServerSettings settings = 
            new ConfigurationBuilder<IServerSettings>()
            .UseEnvironmentVariables()
            .UseCommandLineArgs()
            .Build();

         string address = settings.Address;
         string s = settings.Key;

from config.

aloneguid avatar aloneguid commented on July 17, 2024

@jsobell your issue got me thinking about better design and I couldn't stop :)

from config.

jsobell avatar jsobell commented on July 17, 2024

You're on a roll :)
The use of attributes is a much tidier solution in general, although they need to be on the object rather than the interface. One reason is that the default value initialisers need access to the classes themselves, and you don't want to be referring to classes from within the interface.
Another reason is that if you include custom attributes in the interface, every project using the configuration data needs to have the Config.Net added as a dependency (which is an issue with the existing library).
Certainly removing Option<> would be good, and I'd definitely use attributes for that purpose.

public interface IServerSettings
   {
      string Address { get; set; }
      string Key { get; set; }
   }

public class ServerSettings : IServerSettings
   {
      [Option]
      string Address { get; set; }
      [Option(Alias="productkey", DefaultValue="nokey")]
      string Key { get; set; }
   }

Requiring the attribute also allows easy separation of serialised configuration data, and even a hook to do things like specify customer serialisers etc.
e.g.

  [Option(DefaultValue=Address.Empty, Serialiser=MyTypes.AddressSerialiser)]
  IAddress homeaddress { get; set; }

Not really needed yet (and possibly never) but is a nice way of allowing extension features.

Be wary of changing this library though. Don't pollute the V3 one with the V4 breaking changes, as some people will stick with the current implementation.
You should revert the README file on the master branch back to V3, as people can switch branches to see the V4 stuff. As it is it will cause mucho confusion :)
Sure, leave a comment explaining that there is a V4 branch, but the doco should be with that branch.

from config.

aloneguid avatar aloneguid commented on July 17, 2024

Hi @jsobell, I really like your ideas. Just added you as collaborator on this repo )

I think it can be done in steps in V4, let me know your thoughts:

  1. Having an interface and OptionAttribute on interface members. There is a dependency on Config.Net still, however see the next steps.
  2. As you say, allow specifying attributes in derived classes, and change ConfigurationBuilder to allow specifying those as an option. I really like no dependency on Config.Net in something like model or interfaces library.
  3. Custom serializers. There is ITypeParser interface, we can revisit that if it suits the needs, or add another one.

You're correct about readme file, will fix this now ) I'll branch out V3 and keep V4 in the master (just the way I used to work, master is the most recent code).

Feel free to push to master, this is autopublished to NuGet as alpha 4 at the moment.

from config.

aloneguid avatar aloneguid commented on July 17, 2024

I've also lowered .NET Standard requirement to 1.4, mostly to be able to use in UWP apps.

from config.

jsobell avatar jsobell commented on July 17, 2024

OK, thanks for that. But... I'm no Git guru, so most of the time I'll do it on my own repo and get you to check it and merge :)
I'd hate to be responsible for screwing up the live nuget package :)

Re your other points:

  1. Yes, the class has a dependency, but if the interface is moved to another project that's dependency is removed. As a result your main configuration project needs a reference, but no other projects in your solution do (I think). We'll have to check it and see.
  2. I think you need to use new ConfigurationBuilder<ServerSettings>(), rather than the interface. I suppose you have to decide whether it's correct to dynamically create each property, or have a configuration class. A class is more flexible, as the user can add functions such derived properties or license key decryption stuff.
  3. Yes, your ITypeParser is the type of thing I meant, where MyTypes.AddressSerialiser might refer to a static class that implements that interface if you're overriding the default etc. As I said, probably unnecessary for now :)

from config.

aloneguid avatar aloneguid commented on July 17, 2024

@jsobell I've raised these points as separate issues in the tracker, please feel free to grab any of them ;)

from config.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.