1

I'm working on WinForms application.

I have group of tests classes, each class performs different thing but 80% of classes use almost identical constructors. I'm using reflection to dynamically create class instances in run time from List, there could be dozens of different and same type of tests.

currentTest = (ISystemTest)Activator.CreateInstance(classtype,
                                                    gui,
                                                    param1,
                                                    param2,
                                                    param3,
                                                    param4,
                                                    currentProgressUpdater);

and then run the instance via Action.

As i've said some constructors have slightly different signature. I used to work with switch statements but via reflection it becomes easier to maintain.

To work out the issue with different constructor signatures i have either some creative solution or to create large constructor with default values for test which doesn't need certain data.

So if you have creative solution to this problem i would love to hear it.

Example of constructors:

  • ClassName(gui, param1, param2, param3, progressUpdater) => about 80% of current tests

  • ClassName(gui, param1,param4, param5) => about 10% of current tests

  • ClassName(param4, param6) => 10% of current tests

types are custom classes not string or ints

7
  • 2
    You haven't given us any details about how the signatures differ, or how you'd want to get the values to pass in as arguments. (Also, please pay more attention to your code formatting when you post next time - I've edited it now, but it would have been nice if you'd done it yourself.) Commented Nov 7, 2011 at 7:34
  • I also wonder whether you could just outsource this work to any of the dozens of DI/IoC frameworks, which would supply the arguments automatically based on your configuration Commented Nov 7, 2011 at 7:40
  • Sorry, it is very hard to work with your HTML editor. I always fail to format text in latest Chrome version. I will update how constructors differs Commented Nov 7, 2011 at 7:41
  • @eugeneK the editor isn't html - it is markdown. However, for the purposes of formatting code, just paste it, make sure the code is selected, and hit the "Code Sample" button (has {} as the image), or hit ctrl+k Commented Nov 7, 2011 at 7:43
  • That's what i always do. If i try to re-edit it afterward it totally screws up the format to i leave it untouched. Commented Nov 7, 2011 at 7:46

3 Answers 3

5

The problem you describe is typically solved through dependency injection. You could use a dependency injection framework such as the Managed Extensibility Framework.

edit: You can find some exemples on how to use MEF for DI here and here. Other DI frameworks (unity, autofac, Ninject) work similarily. I have myself worked with both MEF and autofac, and even though the concepts involved need a little learning to get going, they quickly become very intuitive to use and really useful. Autofac is presented as an addictive IoC container, and it's true DI becomes addictive, whatever framework you're using.

Sign up to request clarification or add additional context in comments.

5 Comments

Well i've been told of Unity which is another DI framework but i have no idea how to work with these.
@eugeneK...now is the time to start!
I edited my answer with links to more doccumentation and other DI frameworks.
+1 I can't speak for autofac, but I have used Unity and found it's not that great compared to other IoCs. On the other hand, Ninject is awesome.
I added a link for Ninject to my answer. I never used it though, and never tried Unity either. My experiences with MEF and autofac were both very positive though, each with its pros and cons (MEF being more verbose but more flexible, for example).
0

There is no real way for activator to quess which parameters to inject where in different constructors. You dont want this either since you can burn your fingers pretty quickly.

That said, you can use a dependency injection framework like MEF or Unity or whatever you prefer to do most of the injection for you. this allows you to take control where needed.

Another option would be to work with a setting class which holds common properties rather than a constructor with many arguments.

** EDIT ** attached code example for settings class

class ConsumerSettings
{
    public string Property1 { get; set; }

    public string Property2 { get; set; }
}

class Consumer1
{
    public Consumer1(ConsumerSettings settings)
    {
        if (settings.Property1 == "foo")
        {
        }
    }
}

class Consumer2
{
    public Consumer2(ConsumerSettings settings)
    {
        if (settings.Property2 == "bar")
        {
        }
    }
}

7 Comments

What about Class which holds all params and then passing it as param to all test classes ?
@eugeneK - Exactly, that's the second option in my answer:)
Wouldn't it make me create those properties using switch statement and get me back to square one?
Not really, you construct a Setting Class which is shared by all your test class instances. It's up to the constructor of the test classes to determine which properties from the Setting class they need
@eugeneK - See the code example in my answer for a better explenation
|
-2

You may provide metadata that shows which parameters the test requires. For example, you may declare an attribute that defines a set of parameters:

[Flags]
public enum TestParams { Param1 = 1, Param2 = 2, Param3 = 4, All = Param1 | Param2 | Param3 };
public class ParamsAttribute : Attribute {
    readonly TestParams params;
    public ParamsAttrbiute (TestParams params) {
        this.params = params;
    }
    public TestParams Params { get { return params; } }
} 

Check for the ParamsAttribute and Params property value in your activator and provide necessary arguments only.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.