interface, implementation, and visibility

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hello,

I'm trying to create a component that will be used from .net clients and COM
clients. I've got an object model that looks something like this:

ISystem
IRuntime
IConfiguration
ICollectionOfConfigurableThings
IConfigurableThing

I've created a C# project (starting with the ClassLibrary selection) and
have declared the interfaces, and classes that implement the interfaces.
However, when I want to test the component in a client (in this case, C#)
both the interfaces and the classes are visible. This doesn't seem correct -
a bit too confusing for the users of the object model. What's the correct
way to do this - any good samples out there?

I'd like the client application to be able to do the follow:

ISystem s = new ISystem();
IConfiguration c = s.Configuration;
IConfigurableThing t = c.CreateConfigurableThing("name", "type");
t.SomeProperty = "x";
c.ICollectionOfConfigurableThings.Add(t);

Thanks,
Ken
 
khalprin said:
Hello,

I'm trying to create a component that will be used from .net clients and COM
clients. I've got an object model that looks something like this:

ISystem
IRuntime
IConfiguration
ICollectionOfConfigurableThings
IConfigurableThing

I've created a C# project (starting with the ClassLibrary selection) and
have declared the interfaces, and classes that implement the interfaces.
However, when I want to test the component in a client (in this case, C#)
both the interfaces and the classes are visible. This doesn't seem correct -
a bit too confusing for the users of the object model. What's the correct
way to do this - any good samples out there?

I'd like the client application to be able to do the follow:

ISystem s = new ISystem();

That is not possible. You can't create instances of an interface.
IConfiguration c = s.Configuration;
IConfigurableThing t = c.CreateConfigurableThing("name", "type");
t.SomeProperty = "x";

As you only access those objects through interfaces, the actual classes
doesn't have to be accessible. You can make those classes private.
c.ICollectionOfConfigurableThings.Add(t);

An interface is not a property of the object. If the object contains a
collection that implements that interface, you have to expose the
collection through a property.
 
Goran,

Thanks for the reply.

I understand your statements, I guess I wasn't very careful when describing
the way the client app would use the component - it was mostly just to show
the steps involved in using the different objects. My question is what kind
of visibility the interface and class declarations should have. I don't want
the client apps to see both classes and the interfaces.

Should I make both the interface and the class public, as below? This is
the way I originally worked it, but the client app can see the ISystem
interface and the System class, as well as the IConfiguration interface and
the Configuration class.

When I make one or the other 'not public', I run in to errors that state the
level of access conflicts between the classes and interfaces.

public interface IConfiguration
{
....
}

public class Configuration : IConfiguration
{
....
}

public interface ISystem
{
IConfiguration Configuration { get; }
}

public class System : ISystem
{
private Configuration m_Configuration = new Configuration();
public IConfiguration Configuration
{
get { return m_Configuration; }
}
}

Ken
 
It looks like you are using interfaces where nested members could work
better (if the confusion came from the COM world, just start fresh with .NET
where classes are first class citizens).

An interface can be usefull to see an object under multiple personalities
(for example the IComparable interface allows to define how objects of a
given type should be compared, is is not related at all to the real purpose
of this object and is not seen unless explicitelty required).

Here I would just use regular classes :
MySystem s=new MySystem();
Property p=s.Configuration.Add("type","name");
p.Value="x";
etc...
 
What, no interfaces! I'll try that to see how it works. In that case, do I
just mark the classes as '[ComVisible(true)]'
Ken
 
Just create your .NET class and use the regasm tool (the needed COM
interface is created for you by this tool). They are visible by default (you
can mark just those you don't want to expose).

For now it looks like to me you are creating interfaces either thinking this
..NET is similar to COM or thinking that they are needed for COM interop...
Or do you create those interfaces for some other purpose ?

--
Patrice

khalprin said:
What, no interfaces! I'll try that to see how it works. In that case, do
I
just mark the classes as '[ComVisible(true)]'
Ken

Patrice said:
It looks like you are using interfaces where nested members could work
better (if the confusion came from the COM world, just start fresh with
.NET
where classes are first class citizens).

An interface can be usefull to see an object under multiple personalities
(for example the IComparable interface allows to define how objects of a
given type should be compared, is is not related at all to the real
purpose
of this object and is not seen unless explicitelty required).

Here I would just use regular classes :
MySystem s=new MySystem();
Property p=s.Configuration.Add("type","name");
p.Value="x";
etc...
 
I was creating them because I thought they were needed for COM interop, and
also because it forces me to think of them as immutable - it's too easy to
change the members and method parameters of a class, but I think a lot harder
when it's an interface.

One thing I'm still not really clear on is the visibility of the class
members. When using the component in a .NET client app, all the class
members are visible, whether they're part of the 'interface' or not. How is
that normally handled? I don't want the client apps to see everything behind
the 'interface' (sorry, that's the only word I can think of to describe the
demarcation).

There's gotta be a sample that shows how this is normally done...

Thanks for your input.

Patrice said:
Just create your .NET class and use the regasm tool (the needed COM
interface is created for you by this tool). They are visible by default (you
can mark just those you don't want to expose).

For now it looks like to me you are creating interfaces either thinking this
..NET is similar to COM or thinking that they are needed for COM interop...
Or do you create those interfaces for some other purpose ?

--
Patrice

khalprin said:
What, no interfaces! I'll try that to see how it works. In that case, do
I
just mark the classes as '[ComVisible(true)]'
Ken

Patrice said:
It looks like you are using interfaces where nested members could work
better (if the confusion came from the COM world, just start fresh with
.NET
where classes are first class citizens).

An interface can be usefull to see an object under multiple personalities
(for example the IComparable interface allows to define how objects of a
given type should be compared, is is not related at all to the real
purpose
of this object and is not seen unless explicitelty required).

Here I would just use regular classes :
MySystem s=new MySystem();
Property p=s.Configuration.Add("type","name");
p.Value="x";
etc...

--

"khalprin" <[email protected]> a écrit dans le message
de
news: (e-mail address removed)...
Hello,

I'm trying to create a component that will be used from .net clients
and
COM
clients. I've got an object model that looks something like this:

ISystem
IRuntime
IConfiguration
ICollectionOfConfigurableThings
IConfigurableThing

I've created a C# project (starting with the ClassLibrary selection)
and
have declared the interfaces, and classes that implement the
interfaces.
However, when I want to test the component in a client (in this case,
C#)
both the interfaces and the classes are visible. This doesn't seem
correct -
a bit too confusing for the users of the object model. What's the
correct
way to do this - any good samples out there?

I'd like the client application to be able to do the follow:

ISystem s = new ISystem();
IConfiguration c = s.Configuration;
IConfigurableThing t = c.CreateConfigurableThing("name", "type");
t.SomeProperty = "x";
c.ICollectionOfConfigurableThings.Add(t);

Thanks,
Ken
 
This is not needed. The tool does this for you (afaik it creates a
_classname interface).

Visibility rules are here :
http://msdn.microsoft.com/library/d.../cpconqualifyingnettypesforinteroperation.asp

Note that AFAIK :
- private members are not exposed
- you can use the ComVisible attribute to hide a public member from COM

Remember laso that .NET has also some different options for versioning
(putting this in the GAC may help handle this).

Though articles such as :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/useframewktools.asp
recommend creating explicitly the interface, you may still want to try the
simpler approach for now to see if it fits your needs (as a side note the
article likely uses the ClassInterface attribute you are likely missing from
your current code).

Good luck. Hope it helps.

--
Patrice

khalprin said:
I was creating them because I thought they were needed for COM interop, and
also because it forces me to think of them as immutable - it's too easy to
change the members and method parameters of a class, but I think a lot
harder
when it's an interface.

One thing I'm still not really clear on is the visibility of the class
members. When using the component in a .NET client app, all the class
members are visible, whether they're part of the 'interface' or not. How
is
that normally handled? I don't want the client apps to see everything
behind
the 'interface' (sorry, that's the only word I can think of to describe
the
demarcation).

There's gotta be a sample that shows how this is normally done...

Thanks for your input.

Patrice said:
Just create your .NET class and use the regasm tool (the needed COM
interface is created for you by this tool). They are visible by default
(you
can mark just those you don't want to expose).

For now it looks like to me you are creating interfaces either thinking
this
..NET is similar to COM or thinking that they are needed for COM
interop...
Or do you create those interfaces for some other purpose ?

--
Patrice

"khalprin" <[email protected]> a écrit dans le message
de
What, no interfaces! I'll try that to see how it works. In that case,
do
I
just mark the classes as '[ComVisible(true)]'
Ken

:

It looks like you are using interfaces where nested members could work
better (if the confusion came from the COM world, just start fresh
with
.NET
where classes are first class citizens).

An interface can be usefull to see an object under multiple
personalities
(for example the IComparable interface allows to define how objects of
a
given type should be compared, is is not related at all to the real
purpose
of this object and is not seen unless explicitelty required).

Here I would just use regular classes :
MySystem s=new MySystem();
Property p=s.Configuration.Add("type","name");
p.Value="x";
etc...

--

"khalprin" <[email protected]> a écrit dans le
message
de
news: (e-mail address removed)...
Hello,

I'm trying to create a component that will be used from .net clients
and
COM
clients. I've got an object model that looks something like this:

ISystem
IRuntime
IConfiguration
ICollectionOfConfigurableThings
IConfigurableThing

I've created a C# project (starting with the ClassLibrary selection)
and
have declared the interfaces, and classes that implement the
interfaces.
However, when I want to test the component in a client (in this
case,
C#)
both the interfaces and the classes are visible. This doesn't seem
correct -
a bit too confusing for the users of the object model. What's the
correct
way to do this - any good samples out there?

I'd like the client application to be able to do the follow:

ISystem s = new ISystem();
IConfiguration c = s.Configuration;
IConfigurableThing t = c.CreateConfigurableThing("name", "type");
t.SomeProperty = "x";
c.ICollectionOfConfigurableThings.Add(t);

Thanks,
Ken
 
Aha, so there's the problem. I thought that you had any well founded
reason for wanting the interfaces. ;)

No, you don't need any interfaces at all. Yes, the ComVisible attribute
should do it.
What, no interfaces! I'll try that to see how it works. In that case, do I
just mark the classes as '[ComVisible(true)]'
Ken

Patrice said:
It looks like you are using interfaces where nested members could work
better (if the confusion came from the COM world, just start fresh with .NET
where classes are first class citizens).

An interface can be usefull to see an object under multiple personalities
(for example the IComparable interface allows to define how objects of a
given type should be compared, is is not related at all to the real purpose
of this object and is not seen unless explicitelty required).

Here I would just use regular classes :
MySystem s=new MySystem();
Property p=s.Configuration.Add("type","name");
p.Value="x";
etc...
 
Back
Top