Up to now, I've always decorated my .NET classes that I want to use from VB6 with the [AutoDual] attribute. The point was to gain Intellisense on .NET objects in the VB6 environment. However, the other day I googled AutoDual and the first answer is 'Do Not Use AutoDual'.
I've looked for coherent explanation of why I shouldn't use it, but could not find it.
Can someone here explain it?
I found a reliable way to both provide Intellisense for .NET objects in VB6, while at the same time not breaking the interface. The key is to mark each public method/property in the interface with DispatchID. Then the class must inherit from this interface - in the manner below.
[Guid("BE5E0B60-F855-478E-9BE2-AA9FD945F177")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ICriteria
{
[DispId(1)]
int ID { get; set; }
[DispId(2)]
string RateCardName { get; set; }
[DispId(3)]
string ElectionType { get; set; }
}
[Guid("3023F3F0-204C-411F-86CB-E6730B5F186B")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyNameSpace.Criteria")]
public class Criteria : ICriteria
{
public int ID { get; set; }
public string RateCardName { get; set; }
public string ElectionType { get; set; }
}
What the dispatch ID gives you is the ability to move around items in the class, plus you can now add new things to the class and not break the binary compatibility.
I think this sums it up:
Types that use a dual interface allow
clients to bind to a specific
interface layout. Any changes in a
future version to the layout of the
type or any base types will break COM
clients that bind to the interface. By
default, if the
ClassInterfaceAttribute attribute is
not specified, a dispatch-only
interface is used.
http://msdn.microsoft.com/en-us/library/ms182205.aspx
It increases the possibility that changing something in that class with the auto dual attribute will break someone else's code when the class is changed. If gives the consumer the ability to do something that will quite possibly cause them issues in the future.
The next option is ClassInterfaceType.AutoDual. This is the quick and dirty way to get early binding support as well (and make the methods show up in VB6 IntelliSense). But it's also easy to break compatibility, by changing the order of methods or adding new overloads. Avoid using AutoDual.
http://www.dotnetinterop.com/faq/?q=ClassInterface
I finally found the link that talks about what is going on with AutoDual and how it works:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7fa723e4-f884-41dd-9405-1f68afc72597
The warning against AutoDual isn't the
fact that dual interfaces is bad but
the fact that it auto-generates the
COM interface for you. That is bad.
Each time the COM interface has to be
regenerated you'll get a new GUID and
potentially new members. If the GUID
changes then you get a brand new
interface/class as far as COM is
concerned. For early binding you'd
have to rebuild the clients each time
the interface was regenerated. The
preferred approach is to define the
COM class interface explicitly with a
GUID. Then all the early binding
clients can use the defined interface
and not worry about it changing on
them during development. That is why
the recommended option is None to tell
the CLR not to auto-generate it for
you. You can still implement the dual
interface though if you need it.
Related
I split an interface, inside a Nuget package library, into a simpler base interface (without one property from the original), and made the original derive from the new base interface.
Instantiation in consuming applications happens through Managed Extensibility Framework (MEF), using property injection with [Import] attributes, and implementations with [Export(typeof(IFooConfigurations))]
This shouldn't be a breaking change, for applications using the old interface and implementation. But in some cases, different libraries are loaded, which use old interface versions and implementations. This results in MissingMethodExceptions at runtime, saying a method or property (get method) does not exist - such as the Configurations list property in the example.
Old:
public interface IFooConfigurations
{
int ConfigurationsIdentifier { get; }
IReadOnlyList<Configuration> Configurations { get; }
}
New:
public interface IBaseFooConfigurations
{
// without the ConfigurationsIdentifier
IReadOnlyList<Configuration> Configurations { get; }
}
public interface IFooConfigurations : IBaseFooConfigurations
{
int ConfigurationsIdentifier { get; }
// Configurations inherited from IBaseFooConfigurations
}
Implementation (not changed)
[Export(typeof(IFooConfigurations)]
public class FooConfigurations : IFooConfigurations
{
// implementations of ConfigurationsIdentifier and Configurations
}
Usage (not changed), resolved through MEF
public class FooApplicationClass
{
[Import]
private IFooConfigurations ConfigurationsOwner { get; set; }
}
It is quite hard to track this error and find possible causes, because it doesn't occur in the usual development environment.
Could it be a solution, to replicate all the old properties and methods, which are now in the base interface, in the new version of the IFooConfigurations interface, with the new keyword, while still deriving from the new IBaseFooConfigurations?
Possible solution?
public interface IFooConfigurations : IBaseFooConfigurations
{
int ConfigurationsIdentifier { get; }
new IReadOnlyList<Configuration> Configurations { get; }
}
EDIT: It seems like keeping the members of the original interface, hiding the inherited ones with the "new" keyword, solved the problem. Probably, older applications and libraries, working with the original interface, couldn't resolve the inherited members as parts of the original interface. However, explicit implementations and mocks can potentially be troublesome with this. There is still testing to be done.
Interface members, inherited from another interface, are not equivalent to members, which are defined in the interface itself. Therefore, moving members to a base interface and inheriting from it, is a breaking change. To be downward compatible, the members of the interface must also be defined in itself, as "new" (in C#).
I confirmed this with a simple test program, referencing different builds of DLLs with the original single interface, the split-up and another with the split-up and duplicate "new" members. So it is not an issue of MEF.
Unfortunately, this problem only occurs at runtime, after a release of the nuget package has already been built.
Let's say I have an interface like this:
public interface IUser
{
int Id { get; }
string Name { get; }
List<IMonthlyBudget> MonthlyBudget { get; }
}
and then I have a model that implements this:
public class User : IUser
{
public int Id { get; set; }
public string Name { get; set; }
public List<IMonthlyBudget> MonthlyBudget { get; set; }
}
and here I have the IMonthlyBudget:
public interface IMonthlyBudget
{
int Id { get; }
float MonthlyMax { get; }
float CurrentSpending { get; }
float MonthlyIncome { get; }
}
Now I have my models. But the issue comes with using SQLite. SQLite can't understand what is the real implementation of IMonthlyBudget. I understand why, but I really don't want remove the interface and expose the real implementation to all the clients that use these models. In my project structure I have a Core project that has all the model interfaces, and the model implementation are in a data access project.
Is there something wrong with how I'm approaching this problem? I assume i'm not the first one to run into a issue like this. Isn't it completely normal practice to keep model interfaces (what repositories etc then use as their return types, parameters and stuff like that) and implement the actual concrete models in a data access project?
And can someone explain why I can't do this:
public class User : IUser
{
public int Id { get; set; }
public string Name { get; set; }
public List<MonthlyBudget> MonthlyBudget { get; set; }
}
MonthlyBudget implements IMonthlyBudget, shouldn't it be completely fine to use the concrete model as the type instead of the the interface when the concrete model actually implements the interface?
A few questions here, so I'll break it down into sections:
Use of Interfaces
It is definitely good practice to interface classes that perform operations. For example, you may have a data service (i.e. data access layer) interface that allows you to do operations to read and modify data in your persistent store. However, you may have several implementations of that data service. One implementation may save to the file system, another to a DBMS, another is a mock for unit testing, etc.
However, in many cases you do not need to interface your model classes. If you're using an anemic business object approach (as opposed to rich business objects), then model classes in general should just be containers for data, or Plain Old CLR Objects (POCO). Meaning these objects don't have any real functionality to speak of and they don't reference any special libraries or classes. The only "functionality" I would put in a POCO is one that is dependent only upon itself. For example, if you have a User object that has a FirstName and LastName property, you could create a read-only property called FullName that returns a concatenation of the two.
POCOs are agnostic as to how they are populated and therefore can be utilized in any implementation of your data service.
This should be your default direction when using an anemic business object approach, but there is at least one exception I can think of where you may want to interface your models. You may want to support for example a SQLite data service, and a Realm (NoSQL) data service. Realm objects happen to require your models to derive from RealmObject. So, if you wanted to switch your data access layer between SQLite and Realm then you would have to interface your models as you are doing. I'm just using Realm as an example, but this would also hold true if you wanted to utilize your models across other platforms, like creating an observable base class in a UWP app for example.
The key litmus test to determining whether you should create interfaces for your models is to ask yourself this question:
"Will I need to consume these models in various consumers and will those consumers require me to define a specific base class for my models to work properly in those consumers?"
If the answer to this is "yes", then you should make interfaces for your models. If the answer is "no", then creating model interfaces is extraneous work and you can forego it and let your data service implementations deal with the specifics of their underlying data stores.
SQLite Issue
Whether you continue to use model interfaces or not, you should still have a data access implementation for SQLite which knows that it's dealing with SQLite-specific models and then you can do all your CRUD operations directly on those specific implementations of your model. Then since you're referring to a specific model implementation, SQLite should work as usual.
Type Compatibility
To answer your final question the type system does not see this...
List<IMonthlyBudget> MonthlyBudget
as being type-compatible with this...
List<MonthlyBudget> MonthlyBudget
In our minds it seems like if I have a list of apples, then it should be type-compatible with a list of fruit. The compiler sees an apple as a type of fruit, but not a list of apples as a type of a list of fruit. So you can't cast between them like this...
List<IMonthlyBudget> myMonthlyBudget = (List<IMonthlyBudget>) new List<MonthlyBudget>();
but you CAN add a MonthlyBudget object to a list of IMonthlyBudget objects like this...
List<IMonthlyBudget> myMonthlyBudget = new List<IMonthlyBudget>();
myMonthlyBudget.Add(new MonthlyBudget());
Also you can use the LINQ .Cast() method if you want to cast an entire list at once.
The reason behind this has to do with type variance. There's a good article on it here that can shed some light as to why:
Covariance and Contravariance
I hope that helps! :-)
I've seen this asked, but the standard answer is
An interface is a way to define a contract to interact with an object.
This is all and well, but I'm in need of a way for a class to describe itself to allow its creation. Specifically, I have interface ITicket which defines an object responsible for selling/buying assets. Different implementations require different parameters. My reflex would have been to do something that looks like:
public interface ITicket{
static List<TicketOptions> GetAvailableOptions();
}
public class TicketOption{
public string Label { get; set; }
public string Type { get; set; }
public string Default { get; set; }
}
Then I could have selected an implementation of ITicket in my GUI, and looped over the parameters to create an interface with IntegerUpDown controls for integers, DecimalUpDown controls for decimals and dropdown boxes for Enums.
Alas, C# won't let me. So here I am, looking for an equivalent. Surely there must be a pattern to let me define a contract to interact with a class without an instance?
Edit: Getting into more details...
My C# application loads IronPython scripts. It scans the /Scripts folder and assumes every python file in there contains a class called Ticket implementing ITicket.
I would like to get a list of available parameters for every script to build an interface. This way developpers can create python scripts that they drop into a folder that add new complex behavior without re-compiling the application.
Everything works well, except automatically (and cleanly) knowing what parameters are needed.
I came across an interface recently that only defined a setter like so:
public interface IAggregationView
{
DataTable SetSiteData { set; }
}
I queried this, and it is believed that this is one of the practices advocated by Microsoft for WebPart design (for SharePoint). In fact this example is directly copied from their examples.
I see this as a bad pattern, I don't see why someone should be able to set a value, and then not be able to read it again, and I believe a setter should always be accompanied with a getter (but not necessarily the other way around).
I'm wondering if anyone can explain the benefit of only having a setter, why Microsoft might be suggesting it in this case, and if it's really a good pattern to be following?
There are two scenarios I can see where this might be reasonable:
it is not possible get the value, for example a password; however, I would replace that with a void SetPassword(string) method, personally
the API it is designed for has no requirement to ever read the value, and it is being restricted purely to expose the minimum required API
Re my first point, a Set... method may not be ideal if the consuming API is essentially an automated mapper that assigns values to properties; in that scenario properties would indeed be preferable.
Re your "I don't see why someone should be able to set a value, and then not be able to read it again" - by the same point, however, it could be argued that someone setting the value already knows the value (they set it), so they have no requirement to do this.
But yes; it is very unusual to have a set-only property.
The role of get and set in interface properties is slightly different from those in classes.
public interface IAggregationView
{
DataTable SetSiteData { set; }
}
class AggregationViewImp : IAggregationView
{
public DataTable SetSiteData { get; set; } // perfectly OK
}
The interface specifies that the property should at least have a public setter. The definition and accessibility of the getter is left to the implementing class.
So if the interface contract only needs to write, get can be left open. No need to demand a public getter.
As a consequence, you cannot really specify a read-only property in interfaces either. Only 'at least read access'.
interface IFoo
{
int Id { get; }
}
class Foo : IFoo
{
public int Id { get; set; } // protected/private set is OK too
}
I can imagine using it for (manual) dependency injection. A class may need to have a collaborator injected that it only uses internally. Of course one would normally choose to do this in the class' constructor, but there may be times when one would wish to change the collaborator at runtime.
Classes that implement the interface may add a getter. Most uses of the property may be via an implementing class, not via the interface itself. In which case most code has the ability to get and set the property. The only reason for the interface may be that there is some common code that accesses a common subset of the methods/properties of a family of classes. That code only requires the setter, not the getter. The interface documents that fact.
An interface is just a facility for declaring a group of operations that are "atomically needed" (e.g. if you need to call method A, you'll need to read property B and set property C).
So as always, it depends.
In my experiences such interfaces crop up due to some special need, not for architectural reasons. For example in ASP.NET applications people sometimes make the Global.asax generated type derive from such an interface when they want to maintain global state. Someone might create an initialization value in a separate part of the application and need to publish it to a global place.
I usually like to replace a set-only property with a SetXxx method and make the method check that it is called at most once. That way I clearly enforce "initialization style" which is much less of a smell (imho).
Certainly one cannot set to never produce such a thing but it is to be avoided and will certainly raise questions during code review.
I need to create some custom attributes, to be used for my reflection functions.
Here is the usecase, as I see it:
the user creates some class and marks it with my special attribute ([ImportantAttribute] for example)
then the user does something with functions from my library. Those functions find classes with [ImportantAttribute] and do something with them
The main problem is that functions in my library expects, that classes wich was marked with [ImportantAttribute] inherit my interface (IMyInterface for example)
Is there any way to let user know if he mark his class with [ImportantAttribute] and forget to inherit IMyInterface during compilation, not in run time. Some way to specify that this attribute is only for classes that inherit IMyInterface.
Same with attributes for properties and fields.
Is there any way to let user know if he mark his class with
[ImportantAttribute] and forget to inherit IMyInterface during
compilation, not in run time
Simple answer: no, this is not possible. Not at compile-time. You can check this at runtime though using reflection.
The best you could do with attributes at compile-time (except some special system attributes such as Obsolete but which are directly incorporated into the compiler) is specify their usage with the [AttributeUsage] attribute.
I've used the strategy you mention in a couple of the frameworks I've built with good success. One such example is for providing metadata to a plug-in infrastructure:
[AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
public class PluginAttribute : Attribute
{
public string DisplayName { get; set; }
public string Description { get; set; }
public string Version { get; set; }
}
public interface IPlug
{
void Run(IWork work);
}
[Plugin(DisplayName="Sample Plugin", Description="Some Sample Plugin")]
public class SamplePlug : IPlug
{
public void Run(IWork work) { ... }
}
Doing so allows me to figure out information about plug-ins without having to instantiate them and read metadata properties.
In my experience in doing so, the only way I've found to enforce that both requirements are met is to perform runtime checks and make sure it is bold and <blink>blinking</blink> in the documentation. It is far from optimal but it is the best that can be done (that I've found). Then again I'm sure there is a better way to go about handling this but so far this has been pretty solid for me.