Tilak
Tilak

Reputation: 30728

How to put constraint on constructor parameters in interface?

How to put constraint on constructor parameters?
Is it a good practice?

I have an interface, and I would require Logger component (to be injected by unity).
How can it be enforced that all derived classes would have Logger component (ILogger) as a parameter?

I could not find any appropriate solution.

Only workaround I have found is to put method Initialize (<parameters>) in the interface. This is an ugly approach, and requires special handling.

Is there any design pattern that address such problems?

Upvotes: 0

Views: 1569

Answers (2)

dzendras
dzendras

Reputation: 4751

Why would you ever want to force such a thing?

Focus on what is the real contract (defined by an interface), not on such an unimportant thing like logging. The contract should be defined in a way, that you can't remove any method/property without loosing the ability to perform core functionality.

For instance if you have an interface:

interface IAdder
{
    double Add(double first, double second);
}

Adding is the core functionality. You could have a third argument ILogger, but without it you can still add. Logging is the implementation detail, which should never be a part of a cotract.

Upvotes: 0

Bob Horn
Bob Horn

Reputation: 34325

You don't need a constraint to force derived classes to have a logger component. Just define the base class constructor to take an ILogger.

public class Foo
{
    public Foo (ILogger logger) { /* some implementation here */ }
}

public class Bar : Foo
{
    public Bar(ILogger logger)
        : base(logger)
    {
        // some implementation here
    }
}

Since Bar derives from Foo, it is forced to use the constructor that takes a logger. You can also make Foo abstract, which would force a user to create an instance of a derived class instead of Foo itself.

When you need to define an interface, don't just consider a C# interface. Abstract classes are perfect for cases like this. It is common to think of abstract classes as interfaces (not a C# interface). What you're asking can't be done with a C# interface because those define contracts, not implementation.

Upvotes: 3

Related Questions