Skip to content

Support for string indexing in .NET#69

Closed
pdenny wants to merge 5 commits intomasterfrom
string_indexing
Closed

Support for string indexing in .NET#69
pdenny wants to merge 5 commits intomasterfrom
string_indexing

Conversation

@pdenny
Copy link
Copy Markdown
Contributor

@pdenny pdenny commented Oct 12, 2016

Hopefully just branching instead of forking and branching is not too egregious a faux pas to cause any sort of heart burn.

These changes are intended to give me the capability to dynamically reference a dynamic key value in C#. As far as I can tell, key paths can only be 'hardcoded'. In other words, you must type out the hierarchy separating each level with a . (e.g. prod.task.task2 [see config.json below for reference]). Other than looping through everything, I wasn't able to see a way dynamically reference a specific key.

Ultimately I want to be able to reference keys of the same name as whichever derived class happens to be implementing the base class at run time. Here's a bit of code to make things a little more clear.

  public class Task2 : BaseExecutable
  {
    var value = GetParameter<string>("param2");
    ...
  }
  public abstract class BaseExecutable
  {
    protected T GetParameter<T>(string key)
    {
      var taskString = GetType().Name;
      dynamic container = prod.task[taskString];
      dynamic paramValue = currentTask[key];
      var typeConverter = TypeDescriptor.GetConverter(typeof(T));
      return (T)typeConverter.ConvertFrom(paramValue);
    }
  }

Example config.json:

{
  "Prod": {
    "task": {
      "task1": {
        "param1": "val1",
        "param2": "val2",
        "param3": "val3"
      },
      "task2": {
        "param1": "val1",
        "param2": "val2"
      },
      "task3": {
        "param1": "val1",
        "param2": "val2",
        "param3": "val3",
        "param4": "val4"
      }
    }
  },
  "All": {
    "CI": {
      "Server": "centroid-ci01.centroid.local",
      "Repo": "https://github.com/ResourceDataInc/Centroid"
    }
  }
}

On a side note, I found that there is one more unit test for Ruby than there are for python or .NET. Being a Ruby dolt and not having any time to do any digging, I did not attempt to understand exactly what it did or create complementary tests in python or .NET. The test is test_respond_to.

* Gimme for python and ruby
* This is needed in .net to dynamically reference configuration values
  based on class name. The referencing code is in a base class, and the
  named configuration key is that of the derived class
Copy link
Copy Markdown
Contributor

@jtroe jtroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the respond_totest asserts that the method call is implemented on the class.

Is the GetParameter<T> functionality something we want implemented in the Config class?

set { RawConfig[index] = value; }
}

public object this[string index]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is object the right return type here? You'd have to do some kind of type manipulation with the result, which would make it less fluent...

Copy link
Copy Markdown
Contributor Author

@pdenny pdenny Oct 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason this returns an object is to mimic this[int index].

@pdenny
Copy link
Copy Markdown
Contributor Author

pdenny commented Oct 12, 2016

I cannot get the rake test:rb to successfully run the tests. However if I run the test exactly as the rakefile does (ruby ruby/test/centroid_test.rb), it is successful. Here's the output when I run it via rake:

$ rake test:rb --trace
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/albacore-2.0.0.rc.6/lib/albacore/project.rb:92: warning: duplicated key at line 95 ignored: :include
** Invoke test:rb (first_time)
** Execute test:rb
ruby/test/centroid_test.rb:2:in `require': cannot load such file -- test/unit (LoadError)
        from ruby/test/centroid_test.rb:2:in `<main>'
rake aborted!
Albacore::CommandFailedError: Command failed with status (1):
  ruby ruby\test\centroid_test.rb
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/albacore-2.0.0.rc.6/lib/albacore/cross_platform_cmd.rb:271:in `raise_failure'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/albacore-2.0.0.rc.6/lib/albacore/cross_platform_cmd.rb:250:in `block in handler_with_message'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/albacore-2.0.0.rc.6/lib/albacore/cross_platform_cmd.rb:114:in `call'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/albacore-2.0.0.rc.6/lib/albacore/cross_platform_cmd.rb:114:in `block in system'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/albacore-2.0.0.rc.6/lib/albacore/cross_platform_cmd.rb:255:in `handle_not_found'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/albacore-2.0.0.rc.6/lib/albacore/cross_platform_cmd.rb:88:in `system'
C:/src/Centroid/Rakefile:81:in `block (2 levels) in <top (required)>'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/task.rb:248:in `call'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/task.rb:248:in `block in execute'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/task.rb:243:in `each'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/task.rb:243:in `execute'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/task.rb:187:in `block in invoke_with_call_chain'
C:/ruby/Ruby22/lib/ruby/2.2.0/monitor.rb:211:in `mon_synchronize'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/task.rb:180:in `invoke_with_call_chain'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/task.rb:173:in `invoke'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:152:in `invoke_task'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:108:in `block (2 levels) in top_level'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:108:in `each'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:108:in `block in top_level'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:117:in `run_with_threads'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:102:in `top_level'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:80:in `block in run'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:178:in `standard_exception_handling'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/lib/rake/application.rb:77:in `run'
C:/ruby/Ruby22/lib/ruby/gems/2.2.0/gems/rake-11.3.0/exe/rake:27:in `<top (required)>'
C:/ruby/Ruby22/bin/rake:23:in `load'
C:/ruby/Ruby22/bin/rake:23:in `<main>'
Tasks: TOP => test:rb
ruby ruby\test\centroid_test.rb

$

Comment thread python/tests.py
my_string = "thekey"
self.assertEqual(config.the_environment[my_string], "TheValue")

unittest.main()
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like I should remove unittest.main() as I was running python without the -m option that the rakefile calls it with.

Comment thread python/tests.py
@property
def _shared_file_path(self):
return 'config.json'
return os.path.normpath('../config.json')
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably roll this back, since the rakefile calls the test from the root directory instead of the test directory.


def shared_file_path
'config.json'
File.join('..','..','config.json')
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably roll this back, since the rakefile calls the test from the root directory instead of the test directory.

@pdenny
Copy link
Copy Markdown
Contributor Author

pdenny commented Oct 12, 2016

Further testing is showing that the all section is overriding (or at least not merging) the active environment block. I'm closing this pull request and will create a new one once it's fixed. I will create a new test for this situation as well.

@pdenny pdenny closed this Oct 12, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants