Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Multiple Interface Question 1

Status
Not open for further replies.

link9

Programmer
Nov 28, 2000
3,387
US
Hello all -

So I'm setting up some boilerplate code to be used internally for a common type of application. The applications will take a file and upload the data to a database. This factors out into two interfaces:
Code:
   public interface IDataUploader
   {
      void Upload(string p_Path, Database p_Database);
   }
   public interface IStatusReporter
   {
      event ProgressChangedEventHandler ProgressChanged;
      event StatusChangedEventHandler StatusChanged;
      event ExceptionRaisedEventHandler ExceptionRaised;
   }
Simple enough. The IDataUploader is responsible for getting the data into the database, and the IStatusReporter is responsible for reporting his progress back to the caller.

Here's my question:
In the form that will declare an instance of a concrete implementation, what would be the desired way to do this? My implementing class implements both interfaces, and I want the form to only know about the interfaces, not the class.

So when I declare the object:

protected IDataUploader m_DataUploader;

Well, I guess you see the problem. I can only set his type to one interface.

For now, I have declared essentially an empty interface that only serves to pull the two together:
Code:
   public interface IUploaderAndStatusReporter : IDataUploader , IStatusReporter{}
But that seems a little ugly to me, and really negates my original intention of keeping the two separate concerns... well, separate.

Is there a more elegant solution to this situation?

Thanks for your input.

-paul

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
Code:
class Implementer : Interface1, Interface2
{
}

class Instanciator
{
 // howsoever
 Implementer imp0 = Factory.Create("Implementer");

 Interface1 imp1 = imp0 as Interface1;
 if ( imp1 != null )
 {
  // treat your object like an Interface1
 }

 Interface2 imp2 = imp0 as Interface2;
 if ( imp2 != null )
 {
  // treat your object like an Interface2
 }
}

mr s. <;)

 
That also crossed my mind. But now, the Instanciator is programming against a class and not an Interface, which means that every time I have a new Implementer, I have to rewrite the Instanciator. That defeats the purpose of doing an Interface in the first place.

The Instanciator should only know about the Interface.

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
one could as easily have written the following:

Code:
class Instanciator
{
 public void Method1(object passed)
 {
  Interface1 imp1 = passed as Interface1;
  if ( imp1 != null )
  {
   // treat your object like an Interface1
  }
 
  Interface2 imp2 = passed as Interface2;
  if ( imp2 != null )
  {
   // treat your object like an Interface2
  }
 }
}

mr s. <;)

 
Ah. I think I see what you're getting at now.

So then I could do this:
Code:
IDataUploader m_Uploader;
IStatusReporter m_StatusReporter;

void someMethod()
{
  m_Uploader = Factory.GetInstance("Type");
  m_StatusReporter = m_Uploader as IStatusReporter;
  Debug.Assert(m_StatusReporter != null);

  m_Uploader.Upload(path, database);
  m_StatusReporter.ProgressChanged += ...;

}
Nice. Thanks.

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
if you're certain that the object exposes the correct interface (and don't mind it blowing up if you're wrong) try direct casting:

Code:
void someMethod()
{
  m_Uploader = Factory.GetInstance("Type");
  m_Uploader.Upload(path, database);
  // if (!m_StatusReporter is IStatusReporter) throw new InvalidCastException(...)
  ((IStatusReporter)m_StatusReporter).ProgressChanged += ...;
}

mr s. <;)

 
I generally prefer the safe querying. The syntax is cleaner, and if you always code this way, you're much more flexible in what you can do.

In this case, the assertion is there to ensure that things are properly in order.

penny.gif
penny.gif

The answer to getting answered -- faq855-2992
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top