1

I'm looking to create a very simple web service that randomly generates data for two data points and makes that data accessible via a web service. I decided to give it a try using ASP.NET Web API.

Here is my DataGenerator class:

public class DataGenerator
{
    private Random rand;
    private Double range;
    private Double sample;
    private Double scaled;

    public DataGenerator(string name, string units, double min, double max, int updateRate)
    {
        try
        {
            Name = name;
            Units = units;
            Min = min;
            Max = max;
            UpdateRate = updateRate;

            Timer timer = new Timer();
            timer.Interval = updateRate;
            timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            timer.Start();

            rand = new Random();
            range = max - min;
            Debug.WriteLine("Instantiated");
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error in Data Generator: " + ex.Message);
        }

    }

    private void OnTimedEvent(object sender, ElapsedEventArgs e)
    {
        try
        {
            range = Max - Min;
            sample = rand.NextDouble();
            scaled = (sample * range) + Min;

            Value = scaled;
            Debug.WriteLine("Value = " + Value);
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error in Data Generator: " + ex.Message);
        }
    }

    public string Name { get; }
    public string Units { get; }
    public double Min { get; set; }
    public double Max { get; set; }
    public int UpdateRate { get; set; }
    public double Value { get; private set; }
}

Here is my ApiController class that instantiates two DataGenerator objects:

public class DataGeneratorsController : ApiController
{
    DataGenerator[] generators;

    public DataGeneratorsController()
    {
        generators = new DataGenerator[]
        {
            new DataGenerator("Temperature", "deg F", 0.0, 200.0, 1000),
            new DataGenerator("Pressure", "psi", 0.0, 100.0, 1000)
        };
    }

    public IEnumerable<DataGenerator> GetAllDataGenerators()
    {
        Debug.WriteLine("Temp = " + generators[0].Value.ToString() + " Pressure = " + generators[1].Value.ToString());
        return generators;
    }
}

In debug mode I'm able to see the data generating just fine in the DataGenerator class, but it is always showing up as 0 in the ApiController class, which I found out is because it is getting re-instantiated each time a request is made from the browser.

How do I get around this? I don't get why the constructor would be called each time. I found a lot of stuff online about dependency injection but I don't see how that explains my problem.

I might be missing something very obvious here as I'm new to both C# and Web API.

2 Answers 2

8

The default service behavior is stateless, which means - yes it will be instantiated every time.
Read on the net about application state in asp.net.
Read about the Session object, the Cache object, the Application object, and maybe some information about data persistence in a database.

Good luck.

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

2 Comments

He could try to use session or caching, but the question is if the penalty in memory is important. Session an object, will cost in a big amount of memory use and is sometimes very risky. When using session and application states, you have to plan it very carefully from the beginning.
@BarrJ That's why he should really research this topic for himself, he must go an learn about application state before delving into more complex patterns like dependency injection. All my intention was to give some pointers to start from ;)
1

That's because this controller is not page specific, please note MVC behavior.

A controller has one to one - relation, or one to many depends on how you use it.

one to one means, one controller controls one page, performs the required actions and once you leave the page to another, a different controller is then called and used.

one to many, more then one page uses one controller (which is not recommended and is bad practice).

What you do here, is one to many, meaning every time you want to get into a page, controller will be called, data will reset and all the method will begin a new.

What you can try to do here is:

1) Use dependency in order to try and prevent the data from resetting:

Dependency introduction

2) extend the controller behavior, so it won't reset with each and every call:

Controllers action filter tutorial

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.