Billa
Billa

Reputation: 5266

Pass parameters in constructor instead of setting propeties

I have used constructor only for Dependency Injection in MVC and created all my application or entity objects with out a construction like below

public class MyEntity
{
    public string FirstName{get;set;}
    public Type PropName{get;set;}
}

However I see many are using constructor for some purpose. I know we can use constructor to initialize something. But what are the scenarios should I consider to create a constructor like below? with readonly fields and setting them

public class Licence
{
    private readonly Instant expiry;
    private readonly IClock clock;

    public Licence(Instant expiry, IClock clock)
    {
        this.expiry=expiry;
        this.clock=clock;
    }

    //some methods & prop goes here
}

I have mostly seen this kind of code in Frameworks like MVC and some high level Application Frameworks designed by Architects.

Upvotes: 1

Views: 121

Answers (2)

Henk Mollema
Henk Mollema

Reputation: 46661

I only use constructors in classes where I use dependency injection or when I want to set data which I don't want to change anymore. For example, a MVC controller:

private readonly IProductService _productService;
private readonly IShoppingCartService _shoppingCartService;

public ProductController(IProductService productService,
                         IShoppingCartService shoppingCartService)
{
    _productService = productService;
    _shoppingCartService = shoppingCartService;
}

For my domain models, I don't create constructors to fill my public properties. That would result in a constructor like this:

public Order(string orderReference,
             string userEmail,
             string paymentIssuer,
             bool? isProcessed,
             ICollection<OrderDetail> orderDetails)
{
    OrderReference = orderReference;
    UserEmail = userEmail;
    PaymentIssuer = paymentIssuer;
    IsProcessed = isProcessed;
    OrderDetails = orderDetails;
}

We can call this constructor this way:

new Order("test", "[email protected]", "test", true, null);

Which makes it completely unclear that the arguments mean, I prefer the object initializer. Which looks like this:

new Order
    {
        OrderReference = "test",
        UserEmail = "[email protected]",
        PaymentIssuer = "test",
        IsProcessed = true
    };

However, I do sometimes create a parameterless constructor for my domain models where I set some default data:

public Order()
{
    UserId = Guid.NewGuid();
    OrderDetails = new List<OrderDetail>();
}

Upvotes: 2

Matt
Matt

Reputation: 2682

Generally you'd pass in parameters in a constructor when you don't want those values to be changed after the object is instantiated; this can apply to a variety of situations, including Dependency Injection. A common case for this is custom Exception classes, where you want to pass on additional information that can't be modified:

public class MyException : Exception
{
    public string MyField { get; private set; }

    public MyException(string myField)
    {
        this.MyField = myField;
    }
}

For Dependency Injection, consider providing a log provider implementation to your class:

public class MyClass
{
    public ILogger Logger { get; private set; }

    public MyClass(ILogger logger)
    {
        this.Logger = logger;
    }
}

In both of these cases, you don't want the properties to change once you create them because they would change the fundamental meaning or behavior of the instance.

Upvotes: 2

Related Questions