Can I disallow other assemblies from inheriting from a class? - c#

I've got something like this:
// This gets implemented by plugin authors to get callbacks about various things.
public interface ExternalPlugin
{
// This gets called by the main application to tell the plugin some data
// is available or similar.
void DoStuff(SomeDataBlob blob);
}
// Data blob for v1 of API
public class SomeDataBlob
{
internal SomeDataBlob(string prop) { Prop = prop; }
// Some piece of data that V1 plugins need
public string Prop { get; private set; }
}
// FUTURE!
// Data blob API v2 of API
public class SomeDataBlobV2 : SomeDataBlob
{
// Can be passed to clients expecting SomeDataBlob no problem.
internal SomeDataBlobV2(string prop, string prop2) :base(prop) { Prop2 = prop2; }
// Some piece of data that V2 plugins need. V2 plugins can cast to this from
// SomeDataBlob, but still can load successfully into older versions that support
// only V1 of the API
public string Prop2 { get; private set; }
}
I have to make SomeDataBlob public so that it can be used as a member of the public interface method ExternalPlugin.DoStuff. However, I would not like to allow clients to inherit from that class and thus be susceptible to the brittle base class problem. (All derivatives of that class should be kept in the same assembly)
Marking the class sealed goes too far because I believe removing sealed is a breaking API change; and even if that isn't, once I ship SomeDataBlobV2 clients could still do the wrong thing and inherit from SomeDataBlob directly.
Is there a way to enforce this kind of pattern?

Make the class internal, and expose an interface instead. Then use the factory pattern to create the correct implementation.
public interface ISomeDataBlob
{
}
internal class SomeDataBlob : ISomeDataBlob
{
}
public class BlobApiFactory
{
ISomeDataBlob Create();
}
You hide the implementation, but still give the user access to everything. You even make unit tests easier for your users ;)
Edit (answer to a comment from the OP)
What I effectively want is some method taking some parameters. I want to be able to add parameters that the main application can provide in a future version if the API without breaking clients. But I don't want clients to be able to create instances of the "parameters" class/interface or otherwise interact with it beyond receiving an instance of it as a parameter
Instead of hiding the APIs you can make sure that all object passed to your library originates from your assembly:
public class YourCoolService
{
public void DoSomething(ISomeDataBlob blob)
{
if (blob.GetType().Assembly != Assembly.GetExecutingAssembly())
throw new InvalidOperationException("We only support our own types");
}
}
Edit2
Just noticed that #RQDQ already provided that solution (didn't notice when answering your comment). If that's the solution you want, accept his answer instead.

/// <summary>
/// This is a dummy constructor - it is just here to prevent classes in other assemblies
/// from being derived from this class.
/// See http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2971840&SiteID=1
/// </summary>
internal MhlAdminLayer() { }
The idea is to have a constructor with no parameters internal. Then the class can't be derived from.
Edit: Sorry, the link in the comment doesn't work any more.
Edit 2:
http://msdn.microsoft.com/en-us/library/vstudio/ms173115.aspx
"You can prevent a class from being instantiated by making the constructor private ... "

If you are hell bent on not using sealed AND still using classes, you can enforce this at runtime. In otherwords, at your API boundary, inspect the classes involved and make sure they come from your assembly.
A simple example:
public void Bar(Foo foo)
{
if (foo.GetType().Assembly != this.GetType().Assembly)
throw new InvalidOperationException("It's not one of mine!");
}
public class Foo
{
}

As far as I know, interfaces are the way to do this. It would be an API breaking change, but it would mean you could do what you want.
public interface ExternalPlugin
{
void DoStuff(ISomeDataBlob blob);
}
// Interfaces:
public interface IDataBlob
{
string Prop { get; }
}
public interface IDataBlobV2 : IDataBlob
{
string Prop2 { get; }
}
// Data blob for v1 of API
internal class SomeDataBlob : IDataBlob
{
internal SomeDataBlob(string prop) { Prop = prop; }
public string Prop { get; private set; }
}
// FUTURE!
// Data blob API v2 of API
public class SomeDataBlobV2 : SomeDataBlob, IDataBlobV2
{
// Can be passed to clients expecting SomeDataBlob no problem.
internal SomeDataBlobV2(string prop, string prop2) : base(prop) { Prop2 = prop2; }
public string Prop2 { get; private set; }
}
And then to make the objects use the factory pattern, e.g.
public static class DataBlobFactory
{
public IDataBlob GetDataBlob(string prop)
{
return new SomeDataBlob(prop);
}
// so on.
}

What I would do is make some sort of factory class that exposes an interface that would pass an instance of whatever version for the specific API your client is using, and hide the implementation with an internal class
You can also use constraints to make it little easier to use, then the client can just put the Type of object they are looking for
public interface IBlobV1 { /*public stuff for V1 here*/ }
internal class BlobV1: IBlobV1 {/*v1 implementation*/ }
public interface IBlobV2 : IBlobV1 {/*public interface for V2 here*/ }
internal class BlobV2:BlobV1,IBlobV2 {/*v2 implementation*/}
public sealed BlobFactory
{
public IBlobV1 CreateVersion1Blob(){/* implementation */}
public IBlobV2 CreateVersion2Blob(){/* implementation */}
public T CreateBlob<T>()
where T: IBlobV1
{ /* implementation */}
}

SomeDataBlob can not be inherited because its only constructor is internal. If you try to implement a derived class in a client application:
class SomeDataBlobClient : SomeDataBlob
{
SomeDataBlobClient():base("TEST")
{
}
}
You will get the following error:
The type 'ClassLibrary1.SomeDataBlob' has no constructors defined
It seems that you solved your own problem.

Related

How to force my classes to use as I thought with T

I've made a class with T. It looks like this.
public interface ISendLogic<T> where T : NarcoticsResult
{
ChangeType Change_New();
ChangeType Change_Cancel();
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
public class SendLogic<T> : ISendLogic<T> where T : NarcoticsResult
{
private eReportType _type;
private bool Send_Change()
{
// Send to server by xml file
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public ChangeType Change_New()
{
_type = change_new;
Send_Change();
}
public ChangeType Change_Cancel()
{
_type = change_cancel;
Send_Change();
}
public PurchaseType Purchase_New()
{
_type = purchase_new;
Send_Purchase();
}
public PurchaseType Purchase_Cancel()
{
_type = purchase_cancel;
Send_Purchase();
}
}
There are two types, ChangeType and PurchaseType
and these are inherited from NarcoticsResult.
I thought the person who want to use this class would use it like this.
// this class can only be used when someone wants to use change function
var logic = SendLogic<ChangeType >();
logic.Change_New();
logic.Change_Cancel();
Here is a question.
I want to force this class to be used only as I thought.
I mean, I want to prevent it to be used like this.
var logic = SendLogic<ChangeType>();
logic.Change_New(); // OK
logic.Purchase_New(); // You should make this class like SendLogic<PurchaseType>()
I thought I add some code which check type of T in every function.
How do you think the way I thought. I think there are better way to fix it
Please tell me a better way
thank you.
Personally, I don't think you need a generic class in this case. What you need is either an abstract base class or an interface. I personally love the interface approach as below:
public interface ISendLogic {
void New();
void Cancel();
}
So now you've got a contract that will force the consumer of your code to use New or Cancel methods only.
The next step you can implement that send logic interface for your specific implementation:
public class ChangeSendLogic : ISendLogic {
private eReportType _type;
public ChangeSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Change()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Change();
}
public void Cancel()
{
_type = change_cancel;
Send_Change();
}
}
public class PurchaseSendLogic : ISendLogic {
private eReportType _type;
public PurchaseSendLogic(
/*you can put the necessary parameters in the constructor
and keep it as private fields in the object*/
)
{
}
private bool Send_Purchase()
{
// Send to server by xml file
}
public void New()
{
_type = change_new;
Send_Purchase();
}
public void Cancel()
{
_type = change_cancel;
Send_Purchase();
}
}
From here you can see those two classes handle the implementation for each type nicely. You can think this is as an implementation of single responsibility principle. So if you have one more type, you can just add one more implementation of this interface rather than updating the existing classes.
If you want to hide the creation of those objects, in the next part you can introduce a kind of factory or selector as below:
public enum SendLogicType {
Change,
Purchase
}
public static SendLogicSelector {
public static ISendLogic GetSendLogic(SendLogicType type)
{
switch(type)
{
case SendLogicType.Change:
return new ChangeSendLogic();
case SendLogicType.Purchase:
return new PurchaseSendLogic();
}
}
}
This is how the code will be consumed:
ISendLogic sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Change);
sendLogic.New(); // change new logic executed
sendLogic.Cancel(); // change cancel logic executed
sendLogic = SendLogicSelector.GetSendLogic(SendLogicType.Purchase);
sendLogic.New(); // purchase new logic executed
sendLogic.Cancel(); // purchase cancel logic executed
Hopefully, you can get the idea of my approach. Good luck! :)
Thank you for your comment
I divided it into two parts like below
public class ChangeSendLogic : SendLogic<ChangeType>, IChangeLogic
public class PurchaseSendLogic : SendLogic<PurchaseType>, IPurchaseLogic
And I also divided interface too
public interface IChangeLogic
{
ChangeType Change_New();
ChangeType Change_Cancel();
}
public interface IPurchaseLogic
{
PurchaseType Purchase_New();
PurchaseType Purchase_Cancel();
}
And I made SendLogic<T> class to abstract class.
This is because I want to make the person who wants to use this class to use a class that inherits from this class without directly accessing it.
Thank you for your comment. I got a good idea.

How to initialize abstract base constructor when client calls new on DataContract?

I'm trying to come up with a workaround that would accommodate an abstract base class's constructor being initialized when a client consuming my WCF service performs a new() over a DataContract object. I'm aware that the DataContract objects are created as raw, uninitialized objects thus no constructors are called. I ran across the user of the [OnSerializing], [OnSerialized], [OnDeserializing], and [OnDeserialized] attributes, and I've discovered that they are not honored by the serialization engine of WCF unless you explicitly force it to use XML, which is not desired in this specific case. Here's a very simplified coding example of what I'm trying to use.
[DataContract(Namespace = "http://somenamespace/Data/ContractBase/v1")]
public abstract ContractBase
{
[DataMember(IsRequired = true)]
public SomeDataContract BaseClassObject { get; set; }
public string Name { get; set; }
public ContractBase()
{
BaseClassObject = new SomeDataContract("randomConstructorArgument");
Name = "Ezra";
}
}
[DataContract(Namespace = "http://somenamespace/Data/TheClass/v1")]
[KnownType(typeof(ContractBase))]
public sealed class TheClass : ContractBase
{
[DataMember]
public PetDataContract MyPet { get; set; }
[DataMember]
public int SomeIntProperty { get; set; }
public TheClass()
: base()
{
MyPet = new PetDataContract ("Fido");
SomeIntProperty = -1;
}
}
I'm aware that the client performing TheClass myClass = new TheClass(); will not initialize the base constructor since the constructor of TheClass is never called. I attempted to add in methods such as the following to trigger when serialization occurs without any success.
private void Initialize()
{
MyPet = new PetDataContract ("Fido");
SomeIntProperty = -1;
base.Initialize();
}
[OnSerializing]
private void OnSerializing(StreamingContext c)
{
Initialize();
}
The base class would have the Initialize method as well so that the "constructors" would be chained. The constructors themselves would be updated to include the Initialize(); call to use the same common source of code.
Is there a way to handle this without forcing the serialization to be done through the XmlSerializer? My current workaround is to provide a method in the WCF service to create the object on the server and return the post-constructor version.
public TheClass CreateTheClass(TheClass contract)
{
// Calls the constructor of TheClass and its base constructor.
return new TheClass();
}
This does work as expected, but it's an extra service call that I'd rather avoid because of the network I/O cost. Any help would be extremely appreciated.
Thanks!
According to this article the attributes you mentioned should work nicely with DataContractSerializer. Your last example is a little bit strange - you are trying to use OnSerializing attribute while saying that constructors are not called during deserialization by WCF.
I would suggest to use your approach with Initialize methods marked by OnDeserializing (or OnDeserialized if you wish to call your code after deserialization was completed) attribute.

Is it possible to create an instance of an class without running ANY code from the class? (no ctor, no field initializations)

I have created an engine that takes in 3rd party plugins (DLL's) that implement an interface.
Since I have no control over the code that gets plugged in, I want to be able to run 1 specific method (from the interface) from the correct class (GetTypes loop untill I find the interfaced class ).
Since anyone can create nice constructor code that executes on Activator.CreateInstance, I can solve that by using FormatterServices.GetUninitializedObject. But that does not help when code is being initialized on fields in the class.
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
//I only want this run.
public string MyProperty{
get {
return "ANiceConstString";
}
}
}
The problem with both ways (CreateInstance/GetUninitializedObject) is that the constructor of someotherclass will be run.
Before you start analyze my needs. This is only run in the initializing of the engine to get a set of standard values. If this get'er relies on other initialized values the "plugin" will be marked as failed as there is no valid value returned. If not marked as failed, later on the class will be loaded properly with Activator.CreateInstance().
So stick to this question:
Does .Net support any way to create an 100% non-initialized class?
Update for the answers. I tested this before I posted my question.
For the answer that someotherclass wont run, I allready tested that and it is run if static.
public class myclass : myinterface {
static Tutle test;
public myclass () {
test = new Tutle();
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject does not.
public class myclass : myinterface {
static Tutle test = new Tutle();
public myclass () {
}
public class Tutle {
public Tutle() {
MessageBox.Show("RUN!");
}
}
}
CreateInstance shows the messagebox. GetUninitializedObject shows the messagebox.
Is there a way to get around static field intializers and ctors?
Simply:
var obj = (myclass)FormatterServices.GetUninitializedObject(typeof(myclass));
That will not run the constructor / field initializers. At all. It will not run the constructor for someotherclass; name will be null.
It will, however, execute any static constructor that exists, if necessary under standard .NET rules.
HOWEVER! I should note that this method is not intended for ad-hoc usage; its primary intent is for use in serializers and remoting engines. There is a very good chance that the types will not work correctly if created in this way, if you have not subsequently taken steps to put them back into a valid state (which any serializer / remoting engine would be sure to do).
As an alternative design consideration:
[SomeFeature("ANiceConstString")]
public class myclass : myinterface {
public someotherclass name = new someotherclass()
public myclass() {
//Unknown code
}
}
Now you can access the feature without instantiation; just use:
var attrib = (SomeFeatureAttribute)Attribute.GetCustomAttribute(
type, typeof(SomeFeatureAttribute));
string whatever = attrib == null ? null : attrib.Name;
with:
[AttributeUsage(
AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
public sealed class SomeFeatureAttribute : Attribute
{
private readonly string name;
public string Name { get { return name; } }
public SomeFeatureAttribute(string name) { this.name = name; }
}

Providing Ninject with constructor dependencies it can't resolve?

Disclaimer: I'm quite new to DI and IoC, please forgive any drastic misunderstandings.
Consider a ClassB that requires a object implementing IClassA. Ninject should be able to inject instances of ClassA into the constructor of ClassB, assuming it can construct instances of ClassA:
public class ClassA : IClassA
{
public ClassA(string runtimeDependency) { /* ... */ }
}
public class ClassB : IClassB
{
public ClassB(IClassA depA) { /* ... */ }
}
public sealed class TestBootstrapModule : NinjectModule
{
public override void Load()
{
Bind<IClassA>().To<ClassA>();
Bind<IClassB>().To<ClassB>();
}
}
Now, let's say some runtime logic is involved in deriving the string runtimeDependency provided to ClassA. How should I provide Ninject with runtimeDependency so that it can provide ClassB with instances of ClassA?
The string will only be determined once, so I don't need to worry about injecting a new value into each instance.
One way to do it is to provide the ClassA via a method. Also keep in mind that with Ninject 2, you don't need modules and can do bindings directly in the Kernel.
Bind<IClassA>().ToMethod(_ =>
{
// do something interesting with a runtimeDependancy
return new ClassA(someInterestingVariable);
});
I'm really taking a stab as to when your runtime variable is available and it's scope.
There are a few options here depending on your design, and specific problem. The first, easiest solution is to just provide the value when you request your service from Ninject
Kernel.Get<IClassA>("runtimeDependencyValue");
If this is not possible however, things get a bit more interesting. The way I've solved this previously is to actually create contextual bindings to System.String itself.
Say if I want to bind a connection string, I'll create a custom attribute:
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class ConnectionStringAttribute : Attribute
{
/// <summary>
/// Denotes the setting that you want to populate the given property with.
/// </summary>
public string SettingName { get; private set; }
public ConnectionStringAttribute(string configSettingName = "")
{
SettingName = configSettingName;
}
}
and then I decorate my service constructor like this:
public class ClassA : IClassA
{
public ClassA([ConnectionString("AppDB")] string runtimeDependency) { /* ... */ }
}
Finally, my binding will look something like this:
Bind<string>()
.ToMethod(ctx =>
{
var attr = (ConnectionStringAttribute)context.Request.Target.GetCustomAttributes(typeof(ConnectionStringAttribute), true).First();
string settingName = string.IsNullOrEmpty(attr.SettingName) ? context.Request.Target.Name : attr.SettingName;
return ConfigurationManager.ConnectionStrings[settingName].ConnectionString;
})
.WhenTargetHas<ConnectionStringAttribute>();
You get the idea. Hope this helps :)

C# - using polymorphism in classes I didn't write

What is the best way to implement polymorphic behavior in classes that I can't modify? I currently have some code like:
if(obj is ClassA) {
// ...
} else if(obj is ClassB) {
// ...
} else if ...
The obvious answer is to add a virtual method to the base class, but unfortunately the code is in a different assembly and I can't modify it. Is there a better way to handle this than the ugly and slow code above?
Hmmm... seems more suited to Adapter.
public interface ITheInterfaceYouNeed
{
void DoWhatYouWant();
}
public class MyA : ITheInterfaceYouNeed
{
protected ClassA _actualA;
public MyA( ClassA actualA )
{
_actualA = actualA;
}
public void DoWhatYouWant()
{
_actualA.DoWhatADoes();
}
}
public class MyB : ITheInterfaceYouNeed
{
protected ClassB _actualB;
public MyB( ClassB actualB )
{
_actualB = actualB;
}
public void DoWhatYouWant()
{
_actualB.DoWhatBDoes();
}
}
Seems like a lot of code, but it will make the client code a lot closer to what you want. Plus it'll give you a chance to think about what interface you're actually using.
Check out the Visitor pattern. This lets you come close to adding virtual methods to a class without changing the class. You need to use an extension method with a dynamic cast if the base class you're working with doesn't have a Visit method. Here's some sample code:
public class Main
{
public static void Example()
{
Base a = new GirlChild();
var v = new Visitor();
a.Visit(v);
}
}
static class Ext
{
public static void Visit(this object b, Visitor v)
{
((dynamic)v).Visit((dynamic)b);
}
}
public class Visitor
{
public void Visit(Base b)
{
throw new NotImplementedException();
}
public void Visit(BoyChild b)
{
Console.WriteLine("It's a boy!");
}
public void Visit(GirlChild g)
{
Console.WriteLine("It's a girl!");
}
}
//Below this line are the classes you don't have to change.
public class Base
{
}
public class BoyChild : Base
{
}
public class GirlChild : Base
{
}
I would say that the standard approach here is to wrap the class you want to "inherit" as a protected instance variable and then emulate all the non-private members (method/properties/events/etc.) of the wrapped class in your container class. You can then mark this class and its appropiate members as virtual so that you can use standard polymorphism features with it.
Here's an example of what I mean. ClosedClass is the class contained in the assembly whose code to which you have no access.
public virtual class WrapperClass : IClosedClassInterface1, IClosedClassInterface2
{
protected ClosedClass object;
public ClosedClass()
{
object = new ClosedClass();
}
public void Method1()
{
object.Method1();
}
public void Method2()
{
object.Method2();
}
}
If whatever assembly you are referencing were designed well, then all the types/members that you might ever want to access would be marked appropiately (abstract, virtual, sealed), but indeed this is unfortunately not the case (sometimes you can even experienced this issue with the Base Class Library). In my opinion, the wrapper class is the way to go here. It does have its benefits (even when the class from which you want to derive is inheritable), namely removing/changing the modifier of methods you don't want the user of your class to have access to. The ReadOnlyCollection<T> in the BCL is a pretty good example of this.
Take a look at the Decorator pattern. Noldorin actually explained it without giving the name of the pattern.
Decorator is the way of extending behavior without inheriting. The only thing I would change in Noldorin's code is the fact that the constructor should receive an instance of the object you are decorating.
Extension methods provide an easy way to add additional method signatures to existing classes. This requires the 3.5 framework.
Create a static utility class and add something like this:
public static void DoSomething(this ClassA obj, int param1, string param2)
{
//do something
}
Add a reference to the utility class on the page, and this method will appear as a member of ClassA. You can overload existing methods or create new ones this way.

Categories

Resources