0

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?

2
  • 3
    You cannot put constraints on constructors with interfaces in C# see here. Commented Nov 24, 2012 at 3:32
  • It's not quite as ugly as you make it seem to have an Initialize method accepting whatever these components need to have. That's the standard approach to this problem anyway. Commented Nov 24, 2012 at 3:56

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.