Allow only internal implementations for public interface - c#

This question is similar to Can I make a type "sealed except for internal types" but with interfaces instead of classes.
I want to make a library with something like:
public class SomeClass {
ISupporter Supporter {get; set;}
}
public interface ISupporter {/*Some public methods*/}
internal interface ISupporterInternal {/*Some secret methods*/}
public class SupporterA : ISupporterInternal {/*Includes some explicit interface impls of ISupporterInternal*/}
public class SupporterB : ISupporterInternal {/*Includes some explicit interface impls of ISupporterInternal*/}
The user of the library should be able to set a supporter object for instances of SomeClass. The user should also be able to use the methods from ISupporter but I don't want the user to create his own implementations of ISupporter and have him assign instances of those implementations.
Is there any way besides throwing an exception when the type of the assigned supporter is not derived from ISupporterInternal.

Related

Is is legal to use a interface variable to potentially hold an object of different classes in a domain model?

In my project, I want to implement the SOLID principles, so that my code may be easier to test and extend later down the line. For this purpose, I am curious if I can use Liskov's Substitution Principle in order to make testing of code easier, by having a production class and a testing class both inherit an interface and act in it's place.
Interface + Object classes
public interface Iinterface {
int commonVariable { get; set; }
}
public class ProductionClass : IInterface{
public commonVariable { get; set; }
//Production variables + functions
public ProductionClass() {}
}
public class TestClass : IInterface {
public commonVariable { get; set; }
//Test variables + functions
public TestClass() {}
}
Domain Model
public class DomainModel() {
//Could object be either of ProductionClass or TestClass without breaking my database?
public virtual IInterface object { get; set; }
}
As ProductionClass and TestClass both inherit IInterface, I know that object of either class can be placed in a IInterface variable.
However, when constructing a database, would a IInterface object be valid?
Would it hold all the data of whatever class gets passed to it, or just the data specified when the interface was defined?
What would happen If I tried to insert an object of a different class in the object? Would the columns for the table be overwritten with the new class' variables?
Should I even be attempting to make TestClass, at this rate?
The class design you show is not an example of LSP (Liskov Substitution Principle). It's rather an example of DI (Dependency Inversion): the concretions (DomainModel) depend on abstractions (IInterface).
To have an LSP case, you'd need:
class Base { }
class Derived : Base { }
void Process(Base item)
{
// here, the method shall not care whether 'item' is in fact
// an instance of 'Base' or 'Derived'
}
"Inherit an interface" is incorrect. "Implement an interface" is correct. The classes cannot inherit interfaces, only implement them.
Having a variable (or a field, or a property) of type IInterface, you can only tell the following: the object I have implements that interface. You have no knowledge about the concrete type of the object - whether it is a TestClass, a ProductionClass or a ThirdPartyClass (unless you check for type explicitly of course). The object might be completely different internally. It might contain all the data you need or no data at all.
As a design suggestion: use interfaces to abstract your services and business entities. Use concrete types (POCO) to represent your DTOs (Data Transfer Objects).

Instantiating C# Class Members in C++ using COM

I would like to create a C# class object in C++ and set its member fields.
Although I am able to create a C++ class object, I am unable to access it's members and set member field values.
/// <summary>
/// Class for AQS Entity
/// </summary>
[ClassInterface(ClassInterfaceType.None)]
[Guid("70F12A44-B91D-474D-BD70-32B1ACE041D6")]
[ProgId("AQSEntity")]
public class AQSEntity : IEntity
{
public AQSEntity()
{
sRecoveryDBName = String.Empty;
arrSourceMailboxesEntity = null;
sQueryString = String.Empty;
}
[MarshalAs(UnmanagedType.BStr)]
public string sRecoveryDBName = string.Empty;
[MarshalAs(UnmanagedType.ByValArray)]
public MailBoxCollection arrSourceMailboxesEntity;
[MarshalAs(UnmanagedType.BStr)]
public string sQueryString;
}
and the IEntity class is defined below
[Guid("5C71057E-9FD9-47D5-B022-8D5F9C7007D3")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IEntity
{
}
In C++,
IEntity* pTest1 = NULL;
hr = CoCreateInstance(__uuidof(**AQSEntity**),NULL,CLSCTX_INPROC_SERVER,__uuidof(IEntity),(void**)&pTest1);
I want to access members of AQSEntity class in C++. But I am unable to access them.
pTest1-> sQueryString
gives error.
'sQueryString' : is not a member of
'AsigraExchange::IEntity' C:\PROJECTS\COM\COMClient\COMClient.cpp 168
Can anyone please suggest where I am wrong.
Thanks,
Gagan
Everything behaves exactly as it should :)
In your C++ project, you are allowed to access all the methods declared on your IEntity interface, which there are none.
Your implementation, i.e. AQSEntity class, should implement all the IEntity members. The methods which are now declared in that class are member of the class, they are not related to IEntity in any way.
This means you need to declare all the required methods inside IEntity interface and then implement them in AQSEntity. Notice that you are also exposing the fields of the class, not the methods. You will have to define methods (or properties, which will get converted to methods on C++ side) and then implement them. Something like:
public interface IEntity
{
public string RecoveryDBName { get; }
}
You also have to specify [MarshalAs] attributes in the interface, although UnmanagedType.BStr is default for strings, so you can omit them.
EDIT:
based on comments, it seems that IEntity is just a marker interface, not intended to be exposed as an API (attributes might be better option here, as IEntity won't be used on client side anyway).
In this case there are two options:
1) better approach, although it requires more work: derive IAQSEntity interface from IEntity, declare methods on it, and implement that on AQSEntity class
2) less work, but more brittle: Mark AQSEntity as ClassInterfaceType.AutoDual instead of ClassInterfaceType.None - this will expose the members to COM clients, but will be much harder to version and it will also expose the base type members.
Here's what I would choose:
[ClassInterface(ClassInterfaceType.None)]
...
[Entity] // instead of IEntity marker interface
public class AQSEntity : IAQSEntity
{
public string RecoveryDbName { get; }
}
[Guid("...")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IAQSEntity // no base interface IEntity!
{
string RecoveryDbName { get; }
}
The only drawback of using Entity attribute instead of IEntity marker interface is if you want to use the interface as constraint for generics
Your interface does indeed not contain any members. You need to put the members into the interface and then implement that interface in your class.

Difference Between Interface and Class [duplicate]

This question already has answers here:
What is the difference between an interface and abstract class?
(38 answers)
Closed 9 years ago.
As the title states i want to know the difference between using the class like this
public class Account
{
public string Username { get; set; }
public string Password { get; set; }
}
and using and Interface like this
public class Account : IAccount
{
public string Username { get; set; }
public string Password { get; set; }
}
public interface IAccount
{
string Username { get; set; }
string Password { get; set; }
}
I am really confused as i find interface is useless as all i can do with it can be done only using Class, Hence, i need someone to clarify things for me.
An interface is a contract: it specifies what members (methods and properties) a class implementing the interface must have. But because it is only a contract, it has no implementations for any of its members. A class can implement zero, one or multiple interfaces.
In contrast: a class is a... well... class of objects (like in taxonomy). For example, an Animal is a class of living things, and a Giraffe is a class of animals. Inheritance expresses this relationship: an Giraffe is an Animal when Giraffe inherits from Animal. It can do anything an animal can do, and more. It can provide implementations for its members, and in .NET a class will inherit from exactly one other class (which is Object unless specified otherwise).
So, if you want to express that your class adheres to one or more contracts: use interfaces. However, you cannot provide an implementation. If you want to express that your class is something, extend a base class. In that case you can provide an implementation, but you can extend only one base class.
For a concrete example:
A linked list, an array list, a stack and a dictionary have something in common: they represent a collection of elements. But their implementations are completely different. The only thing they have in common is the contract they adhere to: ICollection. This means your classes can ask for a collection, any collection: anything that implements ICollection, regardless of its implementation.
On the other hand: a car, a motorcycle and a truck also have something in common: they are wheeled vehicles. But they have more in common than that: they all have a motor, they all spin their tires to go forward. Essentially, they are members of the Vehicle class of objects, and can share (part of) their implementation. However, while a Truck may be a Vehicle and a CargoCarrier, you cannot express this in C#.
Basically:
An interface provides a contract specifying how to talk to an object, but not the specifics of how that object handles that request (apart from parameters and return types etc)
And:
A class (especially an abstract class) provides both the information on how to talk to an object, but in some cases the actual implementation (think overriding a method of a base class).
Interfaces allow you to define a common form of communicating between objects, without caring about the specifics of how they do the things.
An example would be logging:
public interface ILog
{
void WriteMessage(string message);
}
public class ConsoleLogger : ILog
{
public void WriteMessage(string message)
{
Console.WriteLine(message);
}
}
public class MessageBoxLogger : ILog
{
public void WriteMessage(string message)
{
MessageBox.Show(message);
}
}
public void DoSomethingInteresting(ILog logger)
{
logger.WriteMessage("I'm doing something interesting!");
}
Because both ConsoleLogger and MessageBoxLogger implement the ILog interface (the WriteMessage method, any part of code can take an ILog without ever needing to know what it actually does, they only care that it does something - in this case, writing a log message.
So in the code above, either a ConsoleLogger or MessageBoxLogger could be supplied to DoSomethingInteresting it doesn't matter at all because ILog "knows" how to talk to that object.

Type safety through inheritance (2)

This is an extension to my previous question: Type safety through inheritance
I created a new question instead of updating my old as this one dives deeper into this topic.
My original purpose was to declare a method that returns an object of the implementing classes type. One such method might look like GetSimpleClone() in the following:
I have a base interface IEntity that declares the method GetSimpleClone() and is implemented by several other interfaces, for example IPerson.
public interface IEntity<T> : where T : IEntity<T>
{
T GetSimpleClone();
}
public interface IPerson : IEntity<IPerson>
{
}
The interface IAddress also implements IEntity. However another interface IVenue inherits from IAddress. As I described in the beginning, I want the GetSimpleClone() method in IAddress to return an object of type IAddress while the same method in IVenue should return an object of type IVenue. Therefore the declaration of IAddress differs from IPerson as it has to declare a generic type itself:
public interface IAddress<T> : IEntity<T> where T : IAddress<T>
{
}
public interface IVenue : IAddress<IVenue>
{
}
Now the problem is that IPersonhas a reference to IAddress and understandably the compiler forces me to define the generic type of IAddress.
public interface IPerson : IEntity<IPerson>
{
IAddress<"Compiler: Define Type!!"> Address { get; set; }
}
I really can't see a solution to this problem and would appreciate any help from you, even if it is just to say that there is simply no solution. :)
Thanks in advance...
To accomplish that, you will need to introduce yet another generic:
public interface IPerson<T> : IEntity<IPerson<T>>
where T : IAddress<T>
{
IAddress<T> Address { get; set; }
}
The better solution I could think of is just to put aside the safety thing and create a good base IAddress interface with a common methods, like getAddressString, and use it for all types of addresses you may want to have.

Inheriting properties with accessibility modifier in C#

I tried to inherit interface, and make some of the automatically generated set property as private. This is an example.
public class MyClass
{
public interface A
{
int X {get; set;}
}
public interface B : A
{
int Y {get; set;}
}
public class C : A
{
public int X {get; private set;}
}
When I tried to compile it. I got an error 'MyClass.C' does not implement interface member 'MyClass.A.X.set'. 'MyClass.C.X.set' is not public..
I tried with private set; in iterface A, but I got this error again : 'MyClass.A.X.set': accessibility modifiers may not be used on accessors in an interface.
Is this accessibility modifier not allowed in C#?
I tried with private set; in iterface A, but I got this error again
If your interface only requires that a property should be retrievable, you define it as:
public interface A
{
int X {get;} // Leave off set entirely
}
The declaration of an interface defines the public set of members that the implementing type must have. So, if C implements A, it must have a public member for each member defined by the interface.
A defines that any implementing type must have a public property X with a public getter and a public setter. C does not meet this requirement.
You can think of an interface as the minimum functionality that your class must implement. If the interface specifies that a property exposes a get and a set clause, then you must implement a public get and set clause in your class, because only public methods and properties can implicitly implement interfaces.
You can simply leave out the set keyword in the interface property definition if you don't want to expose a public mutator. Then you can make the implementation mutator either public or private.
No it is not allowed. Remember, code which is using an instance of class C must be able to treat it as an interface A, which means that the contract is a public getter and setter for property X.
This applies to class inheritance as well as interface inheritance -- you must follow the contract of the type you are derived from.
If the intent of the code is that property X should not have a public setter, then the interface should be defined with just the { get; }
I believe interface members must be public if the interface itself is public. Your implementation of the property is faulty because of that.

Categories

Resources