MEF: Find type of lazy import - mef

I used InheritedExport attribute, and have a tree of objects. Think IMessageSender where I have SmtpSender, TextSender, HttpPostSender. But through decorator pattern I have additional classes that also inherit this MEF InheritedExport attribute.
However when composing the senders, I do not want to decorators to be composed.
Now Lazy could help, whereas I only retrieve the objects that are not of the Decorator type. But I can't ask Lazy what T actually is. Perhaps metadata could help, but the metadata only applies to the object that has this metadata. I don't want to force implementers (read: developers) to add the correct metadata to their decorator or sender.
Any ideas? Thanks!

I needed to do something similar. In the end I opted to add metadata that gave me the required information, but I can see why that's not ideal for your.
One other possibility would be to switch from using an automatic import via attributes, and explicitly call CompositionService.GetExports instead. Then you'd end up with an IEnumerable of Export objects. This would let you get at the contract name (usually, but not always, the type name) and the contract metadata. I think that the contract metadata always includes the type name, so you'd have the information you're looking for.

You can use the following code, to get the type of a Lazy member:
.GetType().GetProperty("Value").PropertyType

Related

Dagger 2 - Proper way to provide instances within a very own module only

Say I have something like this:
#Module
internal class SeenModule {
#Provides
fun parameter() = Parameter()
#Provides
fun actualThingINeedToInject(parameter: Parameter) = ActualThing(parameter)
}
However, this module only really needs to provide an ActualThing object - in other words, the Parameter is only there because the very own module needs it. I don't want it to be part of the set of dependencies that can be retrieved outside of this module.
The way I'm currently doing this is by defining a custom scope as private and then marking the methods that provide dependencies which shouldn't leave the module with this scope, as well as those in the module where the provided dependencies should be injected, of course. This is a bit annoying because it prevents me from using other scopes in these methods and requires a lot of additional annotating all over the place. What is the proper way to achieve this?
Dagger doesn't really offer "private bindings" in the sense you're asking for, where Parameter would not be injectable from anywhere else. I also advise against using scope annotations for visibility, in part because the Component itself would need to be annotated with that scope annotation, so the scope annotation would simply slightly increase the hassle needed to improperly consume Parameter (and the hassle needed to create a Component that properly consumes Parameter).
I'd offer one of these three alternatives:
Reduce the visibility of Parameter as a class. If Parameter is package-private, you won't be able to refer to it from outside of that Java package, giving you the encapsulation you want.
Use "Subcomponents for Encapsulation", in which you create a subcomponent, install your Parameter (and any related bindings) in a Module bound on the subcomponent, and expose only your ActualThing on the subcomponent's interface. Your subcomponent will be injectable, but your Parameter is not; you can also write a #Provides method that returns your ActualThing from your subcomponent instance.
Grin and bear it, and just document that Parameter is an implementation detail that should not be accessed outside of certain packages. If you are providing objects to external teams who access ActualThing through your Component interface, you can simply decline to put Parameter on your public interface; if you are providing objects to internal teams they will likely have access to change your Dagger structure or access modifiers anyway. You might also ask yourself why Parameter would be useful for another team to consume, and document it as an API if there is a business reason for injecting it.

Intersystems Cache - Correct syntax for %ListOfObjects

The documentation says this is allowed:
ClassMethod GetContacts() As %ListOfObjects(ELEMENTTYPE="ContactDB.Contact")
[WebMethod]
I want to do this:
Property Permissions As %ListOfObjects(ELEMENTTYPE="MyPackage.MyClass");
I get an error:
ERROR #5480: Property parameter not declared:
MyPackage.Myclass:ELEMENTTYPE
So, do I really have to create a new class and set the ELEMENTTYPE parameter in it for each list I need?
Correct syntax for %ListOfObjects in properties is this one
Property Permissions As list of MyPackage.MyClass;
Yes, a property does sometimes work differently than a method when it comes to types. That is an issue here, in that you can set a class parameter of the return value of a method declaration in a straightforward way, but that doesn't always work for class parameters on the class of a property.
I don't think the way it does work is documented completely, but here are some of my observations:
You can put in class parameters on a property if the type of the property is a data-type (which are often treated differently than objects).
If you look at the %XML.Adaptor class it has the keyword assignment statement
PropertyClass = %XML.PropertyParameters
This appears to add its parameters to all the properties of the class that declares it as its PropertyClass. This appears to be an example of Intersystems wanting to implement something (an XML adaptor) and realizing the implementation of objects didn't provide it cleanly, so they hacked something new into the class compiler. I can't really find much documentation so it isn't clear if its considered a usable API or an implementation detail subject to breakage.
You might be able to hack something this way - I've never tried anything similar.
A possibly simpler work around might be to initialize the Permissions property in %OnNew and %OnOpen. You will probably want a zero element array at that point anyway, rather than a null.
If you look at the implementation of %ListOfObjects you can see that the class parameter which you are trying to set simply provides a default value for the ElementType property. So after you create an instance of %ListOfObjects you could just set it's ElementType property to the proper element type.
This is a bit annoying, because you have to remember to do it every time by hand, and you might forget. Or a maintainer down the road might not now to do it.
You might hope to maybe make it a little less annoying by creating a generator method that initializes all your properties that need it. This would be easy if Intersystems had some decent system of annotating properties with arbitrary values (so you could know what ElementType to use for each property). But they don't, so you would have to do something like roll your own annotations using an XData block or a class method. This probably isn't worth it unless you have more use cases for annotations than just this one, so I would just do it by hand until that happens, if it ever does.

C# dynamic type how to access some methods and slef tracking entities

I have use the type dynamic, a new type in .NET 4.0.
I want to use a dynamic type because I want to use some types that in advance I don't know what type is, but I know that all this possible type has some common methods.
In my case, I am using self tracking entities in entity framework 4.0, and I know that all the entities has the methods markedXXX (to set the state of the entity).
Through the dynamic object that I created, I can access and set the properties of one of this entities, but when I try to execute the MarkedAsXXX method I get an exception that says that the object has not definied the method.
I would like to know how to access to this methods. Is it possible?
Because I have a function that can access to the original values and set this values to the current one, but I need to set the entity as Unchenged.
Thanks.
I want to use a dynamic type because I want to use some types that in advance I don't know what type is, but I know that all this possible type has some common methods.
That suggests you should create an interface with those common methods, and make all the relevant types implement the interface.
Through the dynamic object that I created, I can access and set the properties of one of this entities, but when I try to execute the MarkedAsXXX method I get an exception that says that the object has not defined the method.
It's possible that this is due to explicit interface implementation. If the types have those methods declared as public methods in the normal way, it should be fine.
If you really want to use dynamic typing with these types, is there some base interface which declares the MarkedAsXXX methods, which you could cast the objects to before calling those methods? (I'm not familiar with the entity framework, so I don't know the details of those methods.)
Basically, I would try to avoid dynamic typing unless you really need it, partly because of edge cases like this - but if explicit interface implementation is the cause, then casting to that interface should be fine.
If you define an interface to the dynamically generated classes you can call the methods without the hassle of reflection calling.

morphia annotation

I am using mongodb with java and also morphia.
For my usecase i get collection name at run time. So i have a enum of collection names and based on some value i get the corresponding collection name from enum. My entity annotation is as follows
#entity(EnumName.getCollectionName())
But i get the following error
"The value for annotation attribute Entity.value must be a constant expression"
I am actually returning a constant expression only. Could anyone let me know what the issue is.
You can't use some something dynamic within annotations as those are "compile" time features which can't be changed afterwards. So you can only handle constants which you declared there, Enums and Classes. For this a smart compiler may be able to find out that you handle something which may never change, but most wont and will simply error as soon as they see that you're trying asign some function value to an annotation property.
I don't really understand what you're trying to do, but it somehow looks like you try to use one "generic" entity class for several concrete entities. I think this is really bad design.
If you can tell more details, we may be able to give you a proper solution for your problem.
If you simply don't know what Class you have to operate with at runtime, try this.
Declare your concrete entities and fill your enum with those Classes. At Runtime you can do Datastore.find(Enum.YOURCLASS) and morphia will query your appropriate class.

Adding and removing Data Annotation attributes dynamically

I have a little bit of a curve ball for you. Maybe just a design issue...maybe even something as simple as me not understanding Data annotation providers.
Anyway here we go:
I have a class which represents some model data. Let's say it represents a package/box/carton.
It actually represents all of these things so I use the class in several different views. Sometimes I want the attribute of the field Package_Description to be
So that it shows up as Box Number : input box here.
Now if i want it to appear as "Carton Name" my only option would be to sub type it. Or use a separate class to have the annotations for this class. My quandary is that some of the field names are user configurable and therefore I cannot have a static definition!
(By the way i am using third party librarys [Telerik MVC Grid] do display these field names so i cannot change the fact that it's looking at data annotation )
So I just need to know is there a way to add attributes dynamically?
Create an anonymous type on the fly, sub class the original and then add attributes using reflection?
Or what other options are open to me, do I need to somehow implement a different annotation provider?
Attributes are part of the definition of the type. Because of that, you can't modify attributes of existing classes during runtime.
You could create a new type during runtime (not an anonymous type), but I think that's not such a good idea. I'm sure whatever component you're using, it allows you to specify the appearance explicitly.