Mark Hollas Mark Hollas - 26 days ago 9
C# Question

C# Action delegate for API contollers to talk to Services

I have seen this approach before where an API controller uses wrapper that puts a unitofwork object in a Action delegate. Then when the delegate is used, it talks to a service layer method that accepts a model and returns Void. The idea is to pass in the model from the outside scope.

//Controller Base
public void Wrapper(Action<UnitOfWork> action)
{
action(new UnitOfWork());
}

//Controller
[HttpPost]
[Route("user")]
[ResponseType(typeof(Member))]
public async Task<IHttpActionResult> PostUser(Member user)
{

Wrapper(uw => { service.Get(uw, user); });
return Ok(user);
}

//Service
public void Get(UnitOfWork uw, Member model)
{
model = uw.MemberRepository.Get(u => u.UserId == id).FirstOrDefault();

//Member m = uw.MemberRepository.Get(u => u.UserId == id).FirstOrDefault();
//model.Created = m.Created;
//model.ExpiryInDays = m.ExpiryInDays;
//model.Id = m.Id;
}


I feel this is a nice approach and I have seen it in projects before... however when I try the above, the object on the controller does not reflect the change made on the service.

Answer

The problem is that you are trying to change the address the model parameter points to.

Even though Member is a reference type and you can modify it inside the method ,you can't modify the address it points to. (You can modify the parameter's address but not the argument's address)
If you need that you have to use the ref keyword

Check the following example

namespace Test
{
    using System;
    public class MyObject
    {
        public string Value { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyObject obj = new MyObject() { Value = "original" };

            Console.WriteLine(obj.Value);
            Change2(obj);
            Console.WriteLine(obj.Value);
            Change3(ref obj);
            Console.WriteLine(obj.Value);

            Console.ReadKey();
        }

        private static void Change2(MyObject obj)
        {
            obj = new MyObject() { Value="You can't see this outside the method" };

            Console.WriteLine("Inside Change 2 "+obj.Value);
        }

        private static void Change3(ref MyObject obj)
        {
            obj = new MyObject() { Value = "You CAN see this outside the method" };

            Console.WriteLine("Inside Change 3 " + obj.Value);
        }
    }
}
Comments