Suppose I have a CarSystem class, which has a collection of CarParts objects in it. Now I wish to write a stereo plugin to the system, and I wish the format of all plugins to be:
public interface ICarPluginMetaData
{
string Name {get;}
string Description {get;}
int Status {get; set;}
}
public interface ICarPlugin
{
void int setStatus(int newStatus);
}
[Export(typeof(ICarPlugin))]
[ExportMetaData("Name", "Stereo")]
[ExportMetaData("Description","Plays music")]
[ExportMetaData("Status", 0)]
public class StereoPlugin : ICarPlugin
{
[ICarPluginImport("FrontSpeakers")]
public CarPart myFrontSpeakersPointer;
[ICarPluginImport("RearSpeakers")]
public CarPart myRearSpeakersPointer;
[ICarPluginImport("subwoofer")]
public CarPart mysubwooferPointer;
[Export]
public void setStatus(int newStatus)
{
Status = newStatus;
}
}
Now in my CarSystem class, I define exports, however the default behavior is to create 1 static object, and hand it to all those importing it; how would I be able to do the following:
[ExportAsThreadsafe]
public CarPart FrontSpeakers
[ExportAsThreadsafe]
public CarPart RearSpeakers
[ExportAsThreadsafe]
public CarPart Subwoofer
[ExportAsThreadsafe]
public CarPart DashLights
so that when I create a second plugin, running on a separate thread, I get a threadsafe connection to the actual object for all plugins?
One way to provide thread safety in MEF is to perform a separate independent MEF composition in each thread. Everything constructed in that composition is then local to that thread. Any cross-thread access is under your control and you can use normal thread safety techniques.
I'm not clear on whether you want to load multiple stereo plugins and have them available to / bound to one global CarSystem, or if you are simply talking about having multiple CarSystems in different threads, independent of each other. You can do the latter by MEF composing the CarSystem with a particular stereo plugin inside of a thread.
Here's what I've ended up doing (in pseudocode):
Foreach plugin dynamically loaded
{
//Via reflection
Foreach field in the plugin
{
See if the field has an attribute attached
Find the field who's name is the same as it's attribute's name
{
Using some lookup method, find the object in the CarSystem
collection who's name is the same as the attribute name.
create a concurrencyQueue using proxy object
call field.SetValue(pluginObject, new Proxy Object) //Reflection call
}
}
}
I basically said, "screw MEF doing this automatically" and did it myself, using Reflection and custom Attributes. I used MEF to do one way messaging, but for plugin's that needed to alter objects in the CarSystem I used my custom "MEF" style.
Related
I am making a gallery tool that lets you browse and edit objects. I have a 'Library' class that manages the fetching and displaying of the gallery list. I also have an 'ActiveItem' asset that loads all the information of the selected object and deals with modifying it.
Now, there's some information that is stored in the 'library' class (for example the filepath) that I want to use in my activeitem.
I'm a bit confused as to how I can set this up efficiently.
I thought about embedding the activeitem class in the library class, but it gets a bit annoying to have to access all functions and properties of the activeitem through the library class (so instead of writing activeitem.Load() I would have to write lib.activeitem.Load() ). Activeitem already goes 4 levels deep and it's getting a bit much.
Are there other ways of setting this up? Can I store a reference of the library class instance inside the activeitem class, so that the activeitem class can fetch a property of the library instance?
Edit: added some code snippets
This are the class definitions:
class Library
{
...
public string LibDirectory;
...
}
class ActiveAsset
{
...
public SaveAsset()
{
//this method needs to know the LibDirectory property of the libraryclass
}
}
On initiating my winform, I initiate both classes:
Library lib = new Library();
ActiveAsset activeAsset = new ActiveAsset();
Given the concerns in the question comments, if you want ActiveAsset to be able to read information from Library you could change ActiveAsset's constructor to take in Library and store it internally as a private var.
class ActiveAsset
{
private Library _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
If you are worried about design and coupling you could make in interface for Library and then make the constructor use that instead of the Library class
interface ILibrary {
string LibDir { get; set; }
}
class Library : ILibrary {
}
class ActiveAsset
{
private ILibrary _lib
public ActiveAsset(Library lib) {
this._lib = lib
}
public SaveAsset()
{
// reach lib instance from here
this._lib.LibDirectory
//this method needs to know the LibDirectory property of the libraryclass
}
}
As for performance and creating deep levels of nested classes I don't think you will have to worry so much about it, chances are you will hit data save/retrieve performance issues before anything like too many classes. That kind of performance design is only really important when you try to make you code work on small platforms where memory is limited like rasberryPi and such.
I would suggest creating a wrapper class which holds both the Library and the ActiveItem instances. Thus you can have more generalised methods like:
GetAllItems() - gets all items from the library
ActivateItem(Item item) - activates the item provided (stores the given item to a variable in the wrapper class)
etc. Think of that wrapper class as the manager of your application. You would only like to work with that manager regardless of what's beneath it.
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.
Imagine the following scenario in a Xamarin solution:
Assembly A (PCL):
public abstract class MyBaseClass
{
public MyBaseClass()
{
[...]
}
[...]
}
Assembly B (3rd Party Library):
public class SomeLibClass
{
[...]
public void MethodThatCreatesClass(Type classType){
[...]
//I want to allow this to work
var obj = Activator.CreateInstance(classType);
[...]
}
[...]
}
Assembly C (Main project):
public class ClassImplA:MyBaseClass{
[...]
}
public class ClassImplA:MyBaseClass{
[...]
}
public class TheProblem{
public void AnExample(){
[...]
//I want to block these instantiations for this Assembly and any other with subclasses of MyBaseClass
var obj1 = new ClassImplA()
var obj2 = new ClassImplB()
[...]
}
}
How can I prevent the subclasses from being instantiated on their own assembly and allow them only on the super class and the 3rd Party Library (using Activator.CreateInstance)?
Attempt 1
I though I could make the base class with an internal constructor but then, I saw how silly that was because the subclasses wouldn't be able to inherit the constructor and so they wouldn't be able to inherit from the superclass.
Attempt 2
I tried using Assembly.GetCallingAssembly on the base class, but that is not available on PCL projects. The solution I found was to call it through reflection but it also didn't work since the result of that on the base class would be the Assembly C for both cases (and I think that's because who calls the constructor of MyBaseClass is indeed the default constructors of ClassImplA and ClassImplB for both cases).
Any other idea of how to do this? Or am I missing something here?
Update
The idea is to have the the PCL assembly abstract the main project (and some other projects) from offline synchronization.
Given that, my PCL uses its own DB for caching and what I want is to provide only a single instance for each record of the DB (so that when a property changes, all assigned variables will have that value and I can ensure that since no one on the main project will be able to create those classes and they will be provided to the variables by a manager class which will handle the single instantions).
Since I'm using SQLite-net for that and since it requires each instance to have an empty constructor, I need a way to only allow the SQLite and the PCL assemblies to create those subclasses declared on the main project(s) assembly(ies)
Update 2
I have no problem if the solution to this can be bypassed with Reflection because my main focus is to prevent people of doing new ClassImplA on the main project by simple mistake. However if possible I would like to have that so that stuff like JsonConvert.DeserializeObject<ClassImplA> would in fact fail with an exception.
I may be wrong but none of the access modifiers will allow you to express such constraints - they restrict what other entities can see, but once they see it, they can use it.
You may try to use StackTrace class inside the base class's constructor to check who is calling it:
public class Base
{
public Base()
{
Console.WriteLine(
new StackTrace()
.GetFrame(1)
.GetMethod()
.DeclaringType
.Assembly
.FullName);
}
}
public class Derived : Base
{
public Derived() { }
}
With a bit of special cases handling it will probably work with Activator class , but isn't the best solution for obvious reasons (reflection, error-prone string/assembly handling).
Or you may use some dependency that is required to do anything of substance, and that dependency can only be provided by your main assembly:
public interface ICritical
{
// Required to do any real job
IntPtr CriticalHandle { get; }
}
public class Base
{
public Base(ICritical critical)
{
if (!(critical is MyOnlyTrueImplementation))
throw ...
}
}
public class Derived : Base
{
// They can't have a constructor without ICritical and you can check that you are getting you own ICritical implementation.
public Derived(ICritical critical) : base(critical)
{ }
}
Well, other assemblies may provide their implementations of ICritical, but yours is the only one that will do any good.
Don't try to prevent entity creation - make it impossible to use entities created in improper way.
Assuming that you can control all classes that produce and consume such entities, you can make sure that only properly created entities can be used.
It can be a primitive entity tracking mechanism, or even some dynamic proxy wrapping
public class Context : IDisposable
{
private HashSet<Object> _entities;
public TEntity Create<TEntity>()
{
var entity = ThirdPartyLib.Create(typeof(TEntity));
_entities.Add(entity);
return entity;
}
public void Save<TEntity>(TEntity entity)
{
if (!_entities.Contains(entity))
throw new InvalidOperationException();
...;
}
}
It won't help to prevent all errors, but any attempt to persist "illegal" entities will blow up in the face, clearly indicating that one is doing something wrong.
Just document it as a system particularity and leave it as it is.
One can't always create a non-leaky abstraction (actually one basically never can). And in this case it seems that solving this problem is either nontrivial, or bad for performance, or both at the same time.
So instead of brooding on those issues, we can just document that all entities should be created through the special classes. Directly instantiated objects are not guaranteed to work correctly with the rest of the system.
It may look bad, but take, for example, Entity Framework with its gotchas in Lazy-Loading, proxy objects, detached entities and so on. And that is a well-known mature library.
I don't argue that you shouldn't try something better, but that is still an option you can always resort to.
I'm writing a DLL using C# 4.0 which will be used by several C# .NET based desktop applications (let's call them AppA and AppB). It is required that AppA will be able to use certain class' selected fields/properties/functions that won't be even available to AppB. My approach was to use internal modifier for those properties and grant access to AppA by specifying AppA's assembly name in InternalsVisibleTo attribute of the DLL. But internal modifier is also required in some properties which will be accessed in other parts of the DLL but not to be accessed by AppA. Now it appears that there are too many internals which are exposed to AppA which shouldn't be accessible by AppA.
In other words, consider the following properties:
class A
{
internal int ReallyInternal {get; set;}
internal int AppAInternal {get; set;}
}
If I use InternalsVisibleTo attribute for AppA, then both ReallyInternal and AppAInternal properties will be exposed to AppA - where as ReallyInternal shouldn't be exposed to AppA.
How to solve this? Is there any other way to implement this scenario?
Background
Before going to InternalsVisibleTo approach we thought of other ways, like having different interfaces etc. The class library I'm writing will be used by multiple applications. I wanted to have the interface same across applications.
Consider TT4 as a class in the DLL. It's properties will be populated from a physical device via serial communication.
TT4 tt4 = new TT4();
// Some code to populate tt4 object
MessageBox.Show(tt4.SerialNumber);
tt4.SerialNumber = "123";
Because tt4 object will represent a physical device, not all of its properties should be modifiable by all applications. This won't make sense and if we allow this then any application can change the serial number of the device. (Yes, SerialNumber can be written back to the device).
We've only one application (here AppA for example) which will be able to set and change the SerialNumber. Other applications shouldn't do that. It's prevented by making SerialNumber's setter as internal and granting permission to AppA by InternalsVisibleTo.
Please note that providing the library with two classes is not the solution. Say, I've implemented two classes for TT4 - TT4 (cannot write SerialNumber) and TT4Super (can write SerialNumber). When the DLL will be given to clients, they can still see TT4Super and use that.
I'm not the developer of other applications and I have no control of them.
One way to do that would be to extract all the members that should be exposed to AppA to an abstract class (or a parent class in general) and make them protected internal. To access them from AppA it would have to inherit from the abstract class. For instance
public abstract class ParentA
{
internal int ReallyInternal {get; set;}
protected internal int AppAInternal {get; set;}
}
And AppA accesses it the following way:
internal class AinAppA : ParentA
{
internal AinAppA()
{
this.AppAInternal = 1; // can access parents protected members
// this.ReallyInternal = 2; // but pure internal members are not visible
}
}
As a side note, InternalsVisibleTo is not meant to be an access modifier. It's main purpose is to make unit testing easier not to enable communication between production assemblies.
Are you mostly concerned that the designers of AppB are going to do something malicious with your DLL, or that you simply want to prevent them from doing something inadvertently? Making your members internal won't really prevent someone from doing harm via reflection if they want to.
One (admittedly not great) approach you could use is to make these members public, but prevent anyone except AppA from using them, by checking the calling assembly:
private void VerifyCaller(Assembly a)
{
if (a == Assembly.GetExecutingAssembly()) { return; }
var name = a.GetName();
if(name.Name == "AppA" && name.GetPublicKey() == appAPublicKey) { return; }
throw new InvalidOperationException("You can't access this");
}
private string _serialNumber;
public string SerialNumber
{
get { return _serialNumber; }
set
{
VerifyCaller(Assembly.GetCallingAssembly());
_serialNumber = value;
}
}
this should at least prevent anyone from easily using reflection to circumvent your defenses.
I'm a relative newbie to C#, although I am a competent programmer, and I confess that I am totally confused as to whether or not it is a good idea to write custom collection classes. So many people seem to say "don't", yet there is a whole set of base classes for it in C#.
Here is my specific case. I have a timetable application. As part of that, I have a service class, and the service class contains collections of things service-y, such as route links. A route link is itself a custom class:
public class Service
{
public RouteLinks RL; // A collection of RouteLink types
...
}
public class RouteLink
{
public string FirstStopRef;
public string LastStopRef;
public Tracks RouteTrack; // Another collection, this time of Track types
}
So far I have looked at using Dictionary as the type for RouteLinks, because I need to be able to reference them. This is fine in principle. However, the process of adding a RouteLink to the RouteLinks collection involves checking to see whether it is already there, or whether it extends and existing route link, or... And for that, I need a custom Add function.
So why is is such bad practice to create custom collection classes? Why shouldn't I just inherit CollectionBase or DictionaryBase?
I should perhaps add that I am transferring this code from VBA [please don't shoot me :)] and there I HAD to implement custom collections.
Instead of having RouteLinks be a collection type, an easy solution would be to just define another class, let's say RouteLinksRepository. This class will contain a List<RouteLink> and the AddRoute(RouteLink) functionality as well as any other custom logic for interacting with this collection of RouteLink objects. Your service class will then just contain an instance of this repository class.
public class Service
{
public RouteLinksRepository RL; // A collection of RouteLink types
// ...
}
public class RouteLinksRepository
{
public List<RouteLink> RouteLinks;
public bool AddRoute(RouteLink linkToAdd)
{
//Custom logic on whether or not to add link
}
//Your other logic for the class
}
public class RouteLink
{
public string FirstStopRef;
public string LastStopRef;
public Tracks RouteTrack; // Another collection, this time of Track types
}
If the only need is to check on double entries, a HashSet will do (implement a GetHash and Equals). However I guess you are trying to save a route. A route has a order, which means you have a order and List<> garantees the order. Make the collection objects private to hide the implementation.
public class Service
{
private List<RouteLink> RL; // A collection of RouteLink types
...
}
public class RouteLink
{
public string FirstStopRef;
public string LastStopRef;
private List<Track> Tracks; // Another collection, this time of Track types
}