Search code examples
c#asp.net-coredependency-injectionrazor-pages

Count calls to method with Dependency Injection


I'm trying to learn about dependency injection. I'm using .net 6.0 Razor Pages and I want to "count", the number of times a method is called via dependency injection. My Index is as following:

public class IndexModel : PageModel
{
    public ICounter _counter;

    public IndexModel(ICounter counter)
    {
        _counter = counter;
    }
    public int Count { get; set; }
    public void OnPostInfo()
    {
        Count = _counter.Calls(Count);
    }
}

My "counter" class, is as following

public int Number { get; set; }
public int Calls(int Number)
{
    return Number += 1 ;
}

And my interface

public interface ICounter
{
   int Calls(int Number);     
}

My Program.cs class

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSingleton<ICounter, Counter>();

My View.

<div class="card">
    <div class="card-body">
        @Model.Count
    </div>
</div>
<div class="row">
    <form asp-page-handler="Info" method="post">
        <button class="btn btn-default">Push to count</button>
    </form>
</div>

It's added as an Transient in Program.cs. The site is updated via a button, and that "works", but it only updates to 1. But then it stops. It doesn't continue to "2, 3, 4" etc when i push the button that uses the OnPostInfo method.

What am i missing here?


Solution

  • Actually it is not caused by lifetime. It dues to the Count value is not passed to the backend, so backend will always get the int default value 0 for Count.

    You need set a hidden input or route parameter to pass the Count.

    First way to set a hidden input:

    View:

    <div class="card">
        <div class="card-body">
            @Model.Count
        </div>
    </div>
    <div class="row">
        <form asp-page-handler="Info" method="post">
            <input hidden asp-for="Count" value="@Model.Count" /> <!--set the hidden input-->
            <button class="btn btn-default">Push to count</button>
        </form>
    </div>
    

    PageModel:

    public class IndexModel : PageModel
    {
        public ICounter _counter;
    
        public IndexModel(ICounter counter)
        {
    
            _counter = counter;
        }
        [BindProperty]  //add this attribute to get the Count value
        public int Count { get; set; }
        public void OnPostInfo()
        {
            Count = _counter.Calls(Count);
        }
    }
    

    The second way to set a route parameter:

    View:

    <div class="card">
        <div class="card-body">
            @Model.Count
        </div>
    </div>
    <div class="row">                  <!--add asp-route-countNum -->
        <form asp-page-handler="Info" asp-route-countNum="@Model.Count" method="post">
            <button class="btn btn-default">Push to count</button>
        </form>
    </div>
    

    PageModel:

    public class IndexModel : PageModel
    {
        public ICounter _counter;
    
        public IndexModel(ICounter counter)
        {
    
            _counter = counter;
        }
    
        public int Count { get; set; }
        public void OnPostInfo(int countNum)   //add parameter here
        {
            Count = _counter.Calls(countNum);   //change here... 
        }
    }
    

    Result:

    enter image description here