awj
awj

Reputation: 7949

Implementing an interface's `internal set` property on an implementation

I have a (public) interface, IAuditLogConfig which has a property with a public getter and an internal setter:

public interface IAuditLogConfig
{
    int ElementTypeId { get; internal set; }
    
    // ...and other methods
}

Implementations of this interface are instantiated via a factory which is in the same library and which will set the ElementTypeId property.

public IAuditLogConfig Create(int elementTypeId)
{
    var key = ...;
    var auditLogConfig = _auditLogConfigFactory.ComponentExists(key)
                             ? _auditLogConfigFactory.CreateComponent(key)
                             : new GenericAuditLogConfig();

    auditLogConfig.ElementTypeId = elementTypeId;
    
    return auditLogConfig;
}

But how do I declare this property on the implementation classes?

Here's an example of the problem I have when declaring the setter on the GenericAuditLogConfig class which is in the same library:

enter image description here

Upvotes: 2

Views: 1294

Answers (1)

Cédric Moers
Cédric Moers

Reputation: 425

You can create a separate internal interface with a setter for this property. Because the interface is internal, the interface cannot be used outside the assembly.

Explicitly implement IHasElementTypeIdSettable on each type returned from the factory and you should be good to go!

    internal interface IHasElementTypeIdSettable
    {
        // since the class is internal already, you can choose 
        // to leave out the internal keyword on the setter.
        int ElementTypeId { get; internal set; }
    }

    public interface IAuditLogConfig
    {
        int ElementTypeId { get; }
    }

    public class GenericAuditLogConfig : IHasElementTypeIdSettable, IAuditLogConfig
    {
        private int _elementTypeId;

        // exposes a public getter.
        public int ElementTypeId { get { return _elementTypeId; } }

        // explicit implementation of IHasElementTypeIdSettable results in a
        // public getter and setter when cast to the internal interface: IHasElementTypeIdSettable
        // this results in the getter and the setter also being internal
        int IHasElementTypeIdSettable.ElementTypeId
        {
            get { return _elementTypeId; }
            set { _elementTypeId = value; }
        }
    }

    public IAuditLogConfig Create(int elementTypeId)
    {
        var key = ...;
        var auditLogConfig = _auditLogConfigFactory.ComponentExists(key)
                                 ? _auditLogConfigFactory.CreateComponent(key)
                                 : new GenericAuditLogConfig();

        ((IHasElementTypeIdSettable)auditLogConfig).ElementTypeId = elementTypeId;

        return auditLogConfig;
    }

Upvotes: 3

Related Questions