Needs -
To declare shared exports of the same interface. The exports are marked by unique export names so consumers may import a particular flavor of the export.
To inject a common instance of the class into a set of objects but to not share a common instance across sets of objects [This makes me use shared exports using different keys - one set of objects can use a single key to get satisfy their shared import need]
Here is the export class
public interface IMyExport
{
void Display();
}
public class MyExport : IMyExport
{
private Guid _id = Guid.NewGuid();
public void Display()
{
Console.WriteLine("Instance ID = "+_id);
}
}
and here is how I export instances of the class
public static class ExportInitialization
{
[Export("Type A", typeof(IMyExport)),
Export("Type B", typeof(IMyExport))]
public static IMyExport IceCreamExport
{
get
{
return new MyExport();
}
}
}
Consumers may import specific instances in the following manner
[Export]
public class ImporterA
{
private readonly IMyExport _myExport;
[ImportingConstructor]
public ImporterA([Import("Type A")]IMyExport myExport)
{
_myExport = myExport;
}
public void Display()
{
_myExport.Display();
}
}
[Export]
public class ImporterB
{
private readonly IMyExport _myExport;
[ImportingConstructor]
public ImporterB([Import("Type B")]IMyExport myExport)
{
_myExport = myExport;
}
public void Display()
{
_myExport.Display();
}
}
class Program
{
[Import]
public ImporterA ImporterA { get; set; }
[Import]
public ImporterB ImporterB { get; set; }
static void Main(string[] args)
{
new Program().Run();
}
public void Run()
{
var container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
container.ComposeParts(this);
ImporterA.Display();
ImporterB.Display();
Console.ReadKey();
}
}
This used to work fine with .Net 4.0 but when .Net 4.5 is installed - I get the following ouptut
Instance ID = 78bba41a-0c48-44fc-ae69-f0ead96371f9
Instance ID = 78bba41a-0c48-44fc-ae69-f0ead96371f9
Notice that the same instance of the object is returned for both imports. Am I breaking some undocumented rule regarding exporting via static properties?
I found that exporting the specific instances from two distinct static properties ensures that 2 distinct instances are returned.
[Export("Type A", typeof(IMyExport))]
public static IMyExport ExportA
{
get
{
return new MyExport();
}
}
[Export("Type B", typeof(IMyExport))]
public static IMyExport ExportB
{
get
{
return new MyExport();
}
}
This is puzzling since in the unmodified version the static getter was creating a new instance on every get. Not sure if this is the result of some C#/.Net optimization introduced with 4.5 or if this is a MEF issue
This is related to the MEF parts lifetime.
The default for MEF attributes is that components do not say whether they care to get a new instance each time or not.
Meaning that:
Your ExportAttribute does not specify whether exported instances can or should be shared;
Both of the ImportAttributes do not specify whether their import should be shared or not;
The default behavior of MEF is that, if it is not forbidden from sharing instances, it will. Meaning that, according to the documentation, the behavior of .NET 4.5 is the correct one: the instance of MyExport is shared, given that no-one on either side explicitly forbade sharing.
I think that .NET 4.0 had a bug/discrepancy where the static property was called every time, which resulted in what you observed, that is, non shared instances. And you were relying on that bug. I think that the bug finds its origin in a fundamental, framework-wide expectation for properties - it is very unusual to have a static property create a new, semantically distinct, instance for each property call.
I believe you should:
Replace your static property export with a static method export;
Specify the creation policy to non-shared, on either the Export side or the Import side;
Related
Problem Description
I'm trying to implement a very specific sort of cache of objects that I may not be able to instantiate directly (private constructors for instance)
What I want to do is read some information about the particular class, preferably through some kind of interface (which sadly doesn't support static methods defined for every subclass)
In other words:
public class Data
{
public static bool Attribute1() => False;
private Data(...) { ... }
}
public class Cache<T> // T is for instance Data
{
void SomeMethod()
{
bool Value = T.Attribute1()
...
}
}
It's fine if I can make T inherit from some base class or some interface, and to get the attribute through some sort of method or directly. It is very important though that I can
Program multiple data classes A and B, where A.Attribute1() is different from B.Attribute1()
Get the attribute from the data class type without instantiating the data type
Current Solution
I do currently have a solution in the shape of a registry built when the static objects are initialised, like this:
class CacheAttributesRegistry
{
static RegisterAttributes(Type T, bool Attribute1, ...) { ... }
}
class Data
{
static Data() { RegisterAttributes(typeof(Data), true, ...); }
}
class Cache<T>
{
void SomeMethod()
{
bool Value = CacheAttributesRegistry.Attribute1(typeof(T));
}
}
It does exactly what I want, but I'd prefer avoiding a static constructor in every data class, also I don't want it to be possible to accidentally call RegisterAttributes at runtime.
Preferably I'd also avoid reflection because I'd like it to be obvious how to set the attributes for a class without the code magically inferring it in the background.
Am I missing some option or have I just reached some language limitations?
I am facing a unique problem. We have a download functionality in our application in which we have a drop-down which contains type of file user need to download i.e. pdf,csv or excel
To implement this problem we have create one Interface IFileDownaload and three different class clsCSV,ClsPDF and clsExcel which are implemented by IFileDownaload
Now my problem is how to inititate a class on the basis of Dropdown value because i dont want to write down if-else statement
if(option=="pdf") type
because in future if we introduce a new file download type then it will impact us to re-write whole logic again
Any suggestion
You can define abbreviation for each class you have, so that you'll have something like this:
public interface IFileDownload
{
string Abbreviation { get; }
}
public class PDFDonwload : IFileDownload
{
public string Abbreviation { get; private set; }
}
Then you can make some class, i.e. factory, which have instances of all filedownloaders you have and which iterates through their Abbreviations till it finds proper class. It can be implemented like this:
public static class DownloadHander
{
private static List<IFileDownload> _handlers;
static DownloadHander()
{
_handlers = new List<IFileDownload>();
}
public static void Initialize()
{
_handlers.Add(new PDFDonwload());
}
public static Stream HandleDownload(string abbreviation)
{
foreach (var fileDownload in _handlers)
{
if (fileDownload.Abbreviation == abbreviation)
{
//and here you make a stream for client
}
}
throw new Exception("No Handler");
}
}
When I have a number of classes which implement a certain type and those classes are stateless services rather than entities, I use a Registry rather than a Factory.
Your Registry has instances of all the IFileDownload-implementing classes injected into it in an array:
public class FileDownloaderRegistry
{
private readonly IFileDownload[] _downloaders;
public FileDownloaderRegistry(IFileDownload[] downloaders)
{
_downloaders = downloaders;
}
}
You then have a property on IFileDownload which indicates the file type handled by the downloader:
public interface IFileDownload
{
string FileType { get; }
// etc.
}
And finally a method on your Registry which takes the file type and delegates the work to the appropriate downloader:
public string DownloadFile(string fileName, string fileType)
{
var handlingDownloader = _downloaders
.FirstOrDefault(d => d.FileType == fileType);
if (handlingDownloader == null)
{
// Probably throw an Exception
}
return handlingDownloader.Download(fileName);
}
DI containers will often implicitly understand arrays, so just registering the various IFileDownloads should end up with them in the array injected into the Registry's constructor. e.g. with StructureMap you use:
For<IFileDownload>().Use<ClsCSV>();
For<IFileDownload>().Use<ClsPDF>();
For<IFileDownload>().Use<ClsExcel>();
Adding a new IFileDownload is then a matter of writing the class and adding it to the set of IFileDownloads registered with your DI container. You can also have the container manage the lifetimes of each object so (if they're stateless) they're only instantiated once each, when they're first needed.
Consider the following code sample that uses MEF to create an object of type Importer that imports an object of type ImporterExporter which in turn imports an object of type Exporter, i.e. Importer -> ImporterExporter -> Exporter. The catalog is managed by a CompositionUtility (obviously simplified for this example).
I know that MEF will resolve imports recursively on imported parts. However, because I want to have the option to instantiate each of these classes independetly, every class with imports also composes itself in its constructor to resolve those imports.
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
namespace MefRecursionSample
{
class Program
{
static void Main(string[] args)
{
// var importerExporter = new ImporterExporter(); // include this and composition will work
var importer = new Importer();
Console.Write(importer.ImporterExporter.Exporter.Value); // should print 7
Console.ReadKey();
}
}
class CompositionUtility
{
static CompositionUtility()
{
var executingAssembly = Assembly.GetExecutingAssembly();
var assemblyCatalog = new AssemblyCatalog(executingAssembly);
_compositionContainer = new CompositionContainer(assemblyCatalog);
}
private static CompositionContainer _compositionContainer;
private static bool _isComposing;
public static void Compose(object part)
{
_compositionContainer.ComposeParts(part);
}
}
class Importer
{
public Importer()
{
CompositionUtility.Compose(this);
}
[Import]
public ImporterExporter ImporterExporter { get; set; }
}
[Export]
class ImporterExporter
{
public ImporterExporter()
{
CompositionUtility.Compose(this);
}
[Import]
public Exporter Exporter { get; set; }
}
[Export]
class Exporter
{
public int Value { get { return 7; } }
}
}
Running the code as is leads to a composition error "The ComposablePart of type MefRecursionSample.Importer' cannot be recomposed....", obviously because I am trying to explictly compose something that MEF also wants to compose.
What surprised me, was the fact that when I included the first line of the Main method, i.e. create an object of type ImporterExporter without MEF, this "double-composition" no longer caused an exception. Why is that?
Also, how could I make it work such that I could instantiate each of these indepennetly, yet also make them compose themselves when chained as in the sample. I figured I would introduce a boolean flag _compositionInProgress on the CompositionUtility and immediately return from Compose() when the flag is set to avoid the recursive composition. Is there a better way?
The flag I considered setting in the CompositionUtility's Compose method does not work, because there can be cases where the string of automatic imports is interrupted. For instance, in the question's example if Exporter instantiated a class in its constructor using new and this class would want to compose itself. Under the original solution, that class' call to Ccompose would return immediately, leaving the class uncomposed.
Because I want classes to compose themselves (thus making it unneccessary for their users to even know about MEF), the only solution was to establish the rule that classes with an [Export] attribute must not call Compose(this). Because they will be composed automatically by MEF when being imported, this would result in "double composition" and thus throw an exception.
If it is a requirement that classes marked with [Export] have to instantiated independently via new instead of nly imported via MEF, they have to have an addional constructor with a boolean flag which when set well trigger composition of that class. The default behavior, however, has to be no composition in order to avoid the aforementioned "double composition".
why not simply do this?
class Program
{
private static CompositionContainer _compositionContainer;
static void Main(string[] args)
{
//compose the container just one time in your app
var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
_compositionContainer = new CompositionContainer(assemblyCatalog);
var importer = _compositionContainer.GetExportedValue<Importer>();
Console.Write(importer.ImporterExporter.Exporter.Value); // should print 7
Console.ReadKey();
}
}
[Export]
class Importer
{
[ImportingConstructor]
public Importer(ImporterExporter imex)
{
this.ImporterExporter = imex;
}
public ImporterExporter ImporterExporter { get; private set; }
}
[Export]
class ImporterExporter
{
[ImportingConstructor]
public ImporterExporter(Exporter exporter)
{
this.Exporter = exporter;
}
public Exporter Exporter { get; private set; }
}
[Export]
class Exporter
{
public int Value { get { return 7; } }
}
What you really want to do (I think) is calling container.SatisfyImportsOnce() on an object and not ComposeParts .
ComposeParts adds all exports tree to the catalog while SatisfyImportsOnce each object is to itself , composing parts and thats it , no registeration of recursive exports , so you can call constructor or use importing constructor , you can have both.
James.
Hello I have this code here:
Memory.OpenProcess(Processes[0].Id);
Hook.Apply(........);
Memory and Hook are both non-static classes, and openprocess and Apply are both static methods within those classes.
However, the problem is, for each instance of my Memory or Hook, I want to have a different process opened, and a different Hook applied.
What I want to do is:
Memory newMemory = new Memory();
newMemory.OpenProcess(processes[1].Id);
Hook newHook = new Hook();
newHook.Apply(....);
But of course I cannot do this because the methods are static and not particular to each instance.
I cannot change the static methods because these methods are coming from a dll in which I do not have access to the source code.
Any ideas?
**Edit: I want to do this so I can avoid having to rehook the process every time a new thread comes along that is working with a different process.
It seems that you cannot do that by design. The implementor of the classes from the dll you are consuming might have explicitly want to avoid the functionality you are trying to achieve.
You can load each thread in different AppDomain, that would give you different static methods.
Also, ThreadStaticAttribute might be helpful for you. Don't sure if it fits you, but give it a look.
Upd: More info about using AppDomains. Lets assume, that you have 3-rd party class Memory defined as follows. (And you cannot change it, and it uses inner static variables)
// Cannot be changed
public class Memory
{
static int StaticId;
public static void OpenProcess(int id)
{
StaticId = id;
}
public static int GetOpenedId()
{
return StaticId;
}
}
You can write a wrapper, deriving from MarshalByRefObject (that's important):
class MemoryWrap : MarshalByRefObject
{
public void OpenProcess(int id)
{
Memory.OpenProcess(id);
}
public int GetOpenedId()
{
return Memory.GetOpenedId();
}
}
So if you create instances of MemoryWrap not by new keyword, but using AppDomain.CreateInstanceAndUnwrap in another domain, each instance would have it's own static contexts. Example:
class Program
{
static void Main(string[] args)
{
var type = typeof(MemoryWrap);
var domain1 = AppDomain.CreateDomain("Domain 1");
var memory1 = (MemoryWrap)domain1.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);
var domain2 = AppDomain.CreateDomain("Domain 2");
var memory2 = (MemoryWrap)domain2.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName);
memory1.OpenProcess(1);
memory2.OpenProcess(2);
Console.WriteLine(memory1.GetOpenedId());
Console.WriteLine(memory2.GetOpenedId());
Console.ReadLine();
}
}
It would print:
1
2
PS: in that example I didn't do the clean up just for readability (unloading domains with AppDomain.Unload() and other things). Don't forget to do it in you code. + There is some mess with lifetime of objects in another domain, but it is next level of problems)))
I'm not sure I fully understand the question, but I will try to answer anyways.
You could define two new classes:
public class MemoryInstance : Memory
{
private var m_instanceProcessId;
public MemoryInstance(var processId) : base()
{
m_instanceProcessId = processId;
}
public void OpenProcess()
{
Memory.OpenProcess(m_instanceProcessId);
}
}
public class HookInstance: Hook
{
private var m_hookId;
public HookInstance(var hookId) : base()
{
m_hookId = hookId;
}
public void Apply()
{
Hook.Apply(m_hookId);
}
}
Then in your code you could call:
public static void Main(String[] args)
{
MemoryInstance newMemory = new MemoryInstance(processes[1].Id);
HookInstance newHook = new HookInstance(hookId);
newMemory.OpenProcess();
newHook.Apply();
}
See , if the API writers are doing that it must be for some reason , you should consult your API writers for he reason or if they can provide you something at instamnce level.
BUT for circumvent your situation , you can use the method provided The_Smallest above.
or you can make use of Reflection as shown below
Memory m = Activator.CreateInstance("Your Dll Name", true) , here true stands for the calling of private constructor.
But i am not convinced , you should do it , you first call to the API writer to get the reason of doing this.
I have run into a bit of a desgin issue with some code that I have been working on:
My code basic looks like this:
Main COM wrapper:
public class MapinfoWrapper
{
public MapinfoWrapper()
{
Publics.InternalMapinfo = new MapinfoWrapper();
}
public void Do(string cmd)
{
//Call COM do command
}
public string Eval(string cmd)
{
//Return value from COM eval command
}
}
Public static class to hold internal referance to wrapper:
internal static class Publics
{
private static MapinfoWrapper _internalwrapper;
internal static MapinfoWrapper InternalMapinfo
{
get
{
return _internalwrapper;
}
set
{
_internalwrapper = value;
}
}
}
Code that uses internal wrapper instance:
public class TableInfo
{
public string Name {
get { return Publics.InternalMapinfo.Eval("String comman to get the name"); }
set { Publics.InternalMapinfo.Do("String command to set the name"); }
}
}
Does this smell bad to anyone? Should I be using a internal property to hold a reference to the main wrapper object or should I be using a different design here?
Note: The MapinfoWrapper object will be used by the outside world, so I don't really want to make that a singleton.
You are reducing the testability of your TableInfo class by not injecting the MapInfoWrapper into the class itself. Whether you use a global cache of these MapInfoWrapper classes depends on the class -- you need to decide whether it is necessary or not, but it would improve your design to pass a wrapper into TableInfo and use it there rather than referencing a global copy directly inside TableInfo methods. Do this in conjunction with the definition of an interface (i.e., "refactor to interfaces").
I would also do lazy instantiation in the getter(s) of Publics to make sure the object is available if it hasn't already been created rather than setting it in the constructor of MapInfoWrapper.
public class TableInfo
{
private IMapinfoWrapper wrapper;
public TableInfo() : this(null) {}
public TableInfo( IMapinfoWrapper wrapper )
{
// use from cache if not supplied, could create new here
this.wrapper = wrapper ?? Publics.InternalMapInfo;
}
public string Name {
get { return wrapper.Eval("String comman to get the name"); }
set { wrapper.Do("String command to set the name"); }
}
}
public interface IMapinfoWrapper
{
void Do( string cmd );
void Eval( string cmd );
}
public class MapinfoWrapper
{
public MapinfoWrapper()
{
}
public void Do(string cmd)
{
//Call COM do command
}
public string Eval(string cmd)
{
//Return value from COM eval command
}
}
internal static class Publics
{
private static MapinfoWrapper _internalwrapper;
internal static MapinfoWrapper InternalMapinfo
{
get
{
if (_internalwrapper == null)
{
_internalwrapper = new MapinfoWrapper();
}
return _internalwrapper;
}
}
}
Now, when you test the TableInfo methods, you can mock out the MapInfoWrapper easily by providing your own implementation to the constructor. Ex (assuming a hand mock):
[TestMethod]
[ExpectedException(typeof(ApplicationException))]
public void TestTableInfoName()
{
IMapinfoWrapper mockWrapper = new MockMapinfoWrapper();
mockWrapper.ThrowDoException(typeof(ApplicationException));
TableInfo info = new TableInfo( mockWrapper );
info.Do( "invalid command" );
}
I thought about adding this to my original response, but it is really a different issue.
You might want to consider whether the MapinfoWrapper class needs to be thread-safe if you store and use a cached copy. Anytime you use a single, global copy you need to consider if it will be used by more than one thread at a time and build it so that any critical sections (anywhere data may be changed or must be assumed to not change) are thread-safe. If a multithreaded environment must be supported -- say in a web site -- then this might argue against using a single, global copy unless the cost of creating the class is very high. Of course, if your class relies on other classes that are also not thread-safe, then you may need to make your class thread-safe anyway.