Hasnain Latif
Hasnain Latif

Reputation: 65

Can we call a parameterized constructor from a parameterless constructor?

For example I have class like this

public class ABC
{
  private readonly IMemoryCache _cache;
  private readonly IConfiguration _config;
  private readonly IDistributedCache _distributedCache;

  public ABC(IMemoryCache memoryCache, IConfiguration config, IDistributedCache distributedCache)
  {
   _cache = memoryCache;
   _config = config;
   _distributedCache = distributedCache;
  }
  public ABC() : this(IMemoryCache , IConfiguration ,IDistributedCache )
  {
  }
}

As you can see that I have tried to call a Parameterized constructor from a Parameter-less constructor, but that's not possible. Is there any other way to achieve this concept?

Upvotes: 1

Views: 1292

Answers (2)

mtmk
mtmk

Reputation: 6316

You need to pass in concrete implementations of those interfaces, It's just like calling a method. There is nothing magical about this() syntax apart from where it appears. For example if you have a default implementation of IMemoryCache implemented in class DefaultMemoryCache you can just 'new that up' and pass it in:

public ABC() : this(new DefaultMemoryCache(), etc.)
{
}

Alternatively, you can use a static factory method if constructing these dependencies is a bit too complicated:

public static ABC CreateNew()
{
    var others = ...
    var cache = new DefaultCache(others, etc.)
    ...
    return new ABC(cache, etc.);
} 

But if you want to be able to use the interface as your input, this is what you can do: (Now, this is just an example to make a point, I do not recommend doing this since it would be very confusing and fragile)

    public ABC() : this
    (
        (IMemoryCache) Activator.CreateInstance
        (
            Assembly.GetExecutingAssembly().GetTypes().First
            (
                t => typeof(IMemoryCache).IsAssignableFrom(t) && !t.IsInterface
            )
        )
    )
    {
    }

The reflection code snippet above, in essence, what a dependency injection library would do, and you might want to consider using one if your project is suitable for it.

One last thing, just to have a complete answer, of course, you can also implement a body in your overloaded contractors:

public class ABC
{
    private readonly ICache _cache;

    public ABC()
    {
        _cache = new Cache();
    }

    public ABC(ICache cache)
    {
        _cache = cache;
    }
}

: this() syntax is only required if you want to call other constructors in the same class for code reuse.

Upvotes: 3

Welcor
Welcor

Reputation: 3093

use instances not types. create an instance of what ever class fulfills your Interface.

public class ABC
{
  private readonly IMemoryCache _cache;
  private readonly IConfiguration _config;
  private readonly IDistributedCache _distributedCache;

  public ABC(IMemoryCache memoryCache, IConfiguration config, IDistributedCache distributedCache)
  {
   _cache = memoryCache;
   _config = config;
   _distributedCache = distributedCache;
  }
  public ABC() : this(new MemoryCache(), new Configuration(), new DistributedCache() )
  {
  }
}

Upvotes: 1

Related Questions