2

Whats happening right now : i have class service and i have 5 propertys on it:

    public class Service
    {
       public string prop1 { get; set; }
       public string prop2 { get; set; }
       public string prop3 { get; set; }
       public string prop4 { get; set; }
       public string prop5 { get; set; }
    }
the sme class contains 100 methods where all of them want to change this properties, how can i decouple those methods in separate classes/services, so they still can change propertys? 

Are there any other ways than usign reference of those propertys as parameters in methods?

UPDATE

So here is a service class:

 public class Service
    {
        public string prop1 { get; set; }
        public string prop2 { get; set; }
        public string prop3 { get; set; }


        public void ChangePropertyInOtherWay()
        {
            prop3 = "some random string";
        }

        public void ChangeProperty()
        {
            prop1 = "12";
        }

        public void ChangePropertyInSpecialWay()
        {
            prop2 = "monkey";
        }



    }

and the executer which handles execution of the functions.

   public class Executer
    {

        private readonly Service _serv;
        private readonly Dictionary<string, Action> functionlist;

        public Executer(Service serv)
        {
            _serv = serv;
            functionlist = new Dictionary<string, Action>();
            functionlist.Add("ChangePropertyInOtherWay", () => serv.ChangePropertyInOtherWay());
            functionlist.Add("ChangePropertyInOtherWay", () => serv.ChangePropertyInOtherWay());
            functionlist.Add("ChangePropertyInSpecialWay", () => serv.ChangePropertyInSpecialWay());
        }

        public void ExecuteFunction(string functionName)
        {
            //INVOKE ONE of the function from the list
        }

    }

What i want to achieve is to decouple Service from Executer, so in executer i wouldnt need a reference to Service.

Timsen
  • 4,066
  • 10
  • 59
  • 117
  • 4
    If you've gotten to a situation where you have 100 methods which mutate common properties, you need to re-think your design. – Yuval Itzchakov Dec 07 '15 at 13:01
  • 3
    It would really help if you'd show a short but complete example of what you're trying to accomplish, ideally following .NET naming conventions to avoid cognitive dissonance. You could also consider using extension methods. – Jon Skeet Dec 07 '15 at 13:02
  • gonna update code with actual problem – Timsen Dec 07 '15 at 13:03
  • Sorry, I do not understand what you are asking... Should these "properties" behave like - uhm - global variables? Or should these "100 methods" work on these values without disturbing each other? – Shnugo Dec 07 '15 at 13:04
  • @Shnugo update the code – Timsen Dec 07 '15 at 13:13
  • @YuvalItzchakov updated the code. Thats exactly why i am about to rewrite the structure – Timsen Dec 07 '15 at 13:14

2 Answers2

0

This may not be the best way but its how i would do it...

class Program
{
    void Run()
    {
        DataGroup WorkingData = new DataGroup();
        Modify("Put This string in here",new FooMethod(),"prop1",WorkingData);
        Modify("This wont do anything", new BarMethod(), "prop5", WorkingData);

    }

    public void Modify(String Input, InterfaceWithData MethodUsed, String Property, DataGroup Data)
    {
        MethodUsed.FooFunction(Input, Property, Data);
    }

}

interface InterfaceWithData
{
    void FooFunction(String Input, String Property, DataGroup Data);
}


public class DataGroup
{
    public string prop1 { get; set; }
    public string prop2 { get; set; }
    public string prop3 { get; set; }
    public string prop4 { get; set; }
    public string prop5 { get; set; }
}


public class FooMethod :InterfaceWithData
{
    public void FooFunction(String Input, String Property ,DataGroup Data)
    {
        switch (Property)
        {

            case "prop1":
                Data.prop1 = Input;
                break;

            case "prop2":
                Data.prop2 = Input;
                break;
            case "prop3":
                Data.prop1 = Input;
                break;

            case "prop4":
                Data.prop3 = Input;
                break;

            case "prop5":
                Data.prop5 = Input;
                break;
            default :
                throw new System.ArgumentOutOfRangeException("Didnt chose a valid case"); 
        }
    }
}

public class BarMethod:InterfaceWithData
{
    public void FooFunction(String Input, String Property, DataGroup Data)
    {
        Data.prop2 = "Monkey";
        /*Do Something else with the data*/
    }
}

This way once it is set up you can add as many methods as you like as long as you keep the syntax the same as is specified by the interface.

Pomadomaphin
  • 116
  • 6
0

I am not sure why you are trying to do what you're trying to do in that way. Maybe if you can describe the overall problem you are having, instead of asking for a specific solution? Sometimes, that leads to better results (there may be much better ways of solving the overall problem than what you are proposing).

It seems a bit "funky" to be honest.

That said, if you want to continue with the approach for some reason, I recommend Reflection in combination with the nameof expression in C# 6.0 (if performance is not an issue).

Here's an example:

Foo.cs

public class Foo {
    public string MyProperty { get; set; }
    public void ChangePropertyInSomeWay() { ... }
}

Then in your Executer, you can do something like:

functionlist.Add(nameof(Foo.ChangePropertyInSomeWay));

And to invoke it when you have a function name, see this question.

With the above method, your code is actually decoupled (sure, your compiler still needs to know about Foo, but the compiled end result is a string). In the case that your compiler doesn't know about Foo, consider defining some interface that you refer in both the project where the Executer and the Service class is, and then get the name via that.

If you are trying to use strings to decouple parts of your code, then there most likely is a better way, and the above should be seen as a "last resort". Please update your questions with details on why you are doing what you are doing, and for what reason. Then we might be able to solve the problem in new ways.

Community
  • 1
  • 1
Mathias Lykkegaard Lorenzen
  • 15,031
  • 23
  • 100
  • 187