PostSharp contracts make it easy to label individual fields as Required. But I want a class attribute that makes all of the class fields required. I'm guessing I would have to implement a custom aspect to support this.
It seems like it would be a common need for anyone passing around data containers. Can anyone direct me to some code that implements a custom "AllFieldsRequired" aspect in PostSharp?
You can implement PostSharp.Aspects.IAspectProvider:
public class AllFieldsRequiredAttribute : TypeLevelAspect, IAspectProvider
{
IEnumerable<AspectInstance> IAspectProvider.ProvideAspects(object targetElement)
{
Type type = (Type)targetElement;
return type.GetFields().Select(
m => new AspectInstance(m, new ObjectConstruction(typeof(RequiredAttribute))));
}
}
[AllFieldsRequired]
public class Foo
{
public string Bar;
public object Baz;
}
Related
I have a bunch of 3rd party classes, these classes are autogenerated in java and do not have any hierarchy
Here is the RulesPropertyList
enum RulesPropertyType {...}
class RulesPropertyValue {...}
class RulesProperty {
public RulesPropertyType getPropertyTypeCode(){...}
public RulesPropertyValue getPropertyValue() {...}
}
class RulesPropertyList {
public void setNumProperties(int numProperties)
public void setProperties(RulesProperty[] properties)
}
And its Characs* sibling
enum CharacsPropertyType {...}
class CharacsPropertyValue {...}
class CharacsProperty {
public CharacsPropertyType getPropertyTypeCode(){...}
public CharacsPropertyValue getPropertyValue() {...}
}
class CharacsPropertyList {
public void setNumProperties(int numProperties)
public void setProperties(CharacsProperty[] properties)
}
There are more than just Rules* and Characs* families of classes, and classes actually have more fields and deeper structures.
All classes are completely identical except for the prefixes in the class names.
Currently, I have a separate builder method for each set of classes.
def buildRulesPropertyList(props: (RulesPropertyType, RulesPropertValue): RulesPropertyList = {
val properties = props.map { case (type, value) =>
RulesProperty(type, value)
}
val propList = RulesPropertyList
propList.setProperties(properties.toArray)
propList.setNumProperties(properties.length)
propList
}
I have to create such a builder for each family of classes.
Now I only see a possibility to make a generic builder using reflection.
Is there a way in Scala to make such a builder using generics in Scala language?
Is there a way in Scala to make such a builder using generics in Scala language?
yes, but I don't think it's going to be any less code. I think your best move here is to just write some simple code generation for each type. you would feed it a list of family names like Seq("Rules", "Characs", ...) and have it spit out your build${family}PropertyList methods.
in my current project I have to render items in a CellTable received via a RPC call. The columns must be created dynamically and the column types are unknown at compile time.
From the server side, I send a list of the following class to define a row in the table:
public class TableRowDTO implements IsSerializable {
private List<IsTableItemDTO> tableItemDTOs;
public TableRowDTO() {
tableItemDTOs = new ArrayList<IsTableItemDTO>();
}
// getters & setters ...
}
Where each row will contain an item implementing IsTableItemDTO which is a marker interface:
public interface IsTableItemDTO extends IsSerializable {}
Implementing classes depict the actual controls/information to be shown in cells like:
public class TableDateTimeDTO extends IsTableItemDTO {
private Date valueDate;
// ... other fields not necessary for the table
}
Or also:
public class TableCheckBoxDTO extends AbstractTableItemDTO {
private boolean checked;
// ... other fields not necessary for the table
}
And also:
TablePasswordDTO extends AbstractTableItemDTO {
private String valueText;
// ... other fields not necessary for the table
}
Therefore, what I want to do for example in the case I receive a List with {TableCheckBoxDTO, TableDateTimeDTO, TablePasswordDTO} is to render a CellTable with the corresponding widgets.
I've seen this and this, but I don't see how to apply any of the examples to my case especially because I cannot use thigs like Column as I don't have my ContactInfo before hand.
Thanks
You can use the marker interface IsTableItemDTO together with instanceof() and dynamic casts to have a generic Column/Cell.
There are 2 ways:
Create a Composite Cell and add all possible cell types and then display based on what specific sub-type your isTableItemDTO is.
Create a custom cell and render the input (checkbox, text) based on the specific type of your marker interface
I used Jet table (https://code.google.com/p/gwt-jet/) in one of my earlier projects. I believe it has the features you are looking for.
I would like my uiBinder to use a ClientBundle which will provide some runtime customized labels. Kind of a TextResource but not from a text file !
I tried with GwtCreateResource but from the DevGuide it seems like it's not possible. Am I right ? (create() and name() are the only methods available)
What I would like to achieve is something like this:
client bundle:
public interface MyWidgetResources extends ClientBundle {
GwtCreateResource<WidgetLabels> labels();
#Source("lol.css")
CssResource style();
}
labels class:
public final class MyWidgetLabels {
public String title() {
return load("mywidget-title");
}
public String banner() {
return load("mywidget-banner");
}
private String load(String key) {
// load from external..
}
}
uiBinder:
<ui:with type="com.package.MyWidgetResources" field="res"/>
<gwt:SimplePanel>
<gwt:Label text="{res.labels.title}"></gwt:Label>
<gwt:Label text="{res.labels.banner}"></gwt:Label>
</gwt:SimplePanel>
My code looks like this already but res.label.title does not work because GwtCreateResource can only serve as class instantiator (res.labels.create().title()).
Is there a solution for me ? Maybe with a custom ResourceGenerator ?
As long as MyWidgetLabels can be created by GWT.create, you can put anything you want into that type, and you can make it behave however you'd like. You will need the create reference in your uibinder as you suggested at the end of the post to actually build the object, so your lines will look about like this:
<gwt:Label text="{res.labels.create.title}"></gwt:Label>
Each . separated piece (except the first, which is a ui:field/#UiField) is a no-arg method to be called - you declared labels() in MyWidgetResources, create() already existed in GwtCreateResource, and you created title() in your own MyWidgetLabels type.
Since that first piece is a ui:field/#UiField, you could have another that references res.labels.create as something like labels so that later you could instead say:
<gwt:Label text="{labels.title}"></gwt:Label>
Finally, yes, you could build your own ResourceGenerator which would enable you to do whatever you wanted to emit the type in question, as long as you extended the ResourcePrototype type and had a getName() method.
How do I register IPetFactory<TPet> to be resolved with DefaultPetFactory<TPet> where TPet can be any class based on Pet in the example below?
I'd like to be able to resolve IPetFactory<Dog> with DefaultPetFactory<Dog>.
I've just found examples using BasedOn where the Factory itself is based on a class, not the generic argument.
class Pet
{
public string Name { get; set; }
}
class Fish : Pet {}
class Dog : Pet {}
class Cat : Pet { }
interface IPetFactory<TPet> where TPet : Pet;
class DefaultPetFactory<TPet> : IPetFactory<Pet> where TPet : Pet
{
// default implementation
}
My real implementation has a lot of classes based on Pet so I'm looking for a more generic approach than just calling register on each of them.
EDIT:
I found out the problem wasn't what I thought it was. It was due to the generic arguments and an exception of “the arity of the generic type definition” which caused my problems.
And I over-simplified my example. In my real implementation I have to generic arguments and it turns out Windsor need the the same generic parameters to be able to resolve the type.
If I do like this it won't work.
class Owner
{
}
class DefaultPetFactory<TPet> : IPetFactory<Owner, TPet> where TPet : Pet
{
// default implementation
}
If I do like this it will:
class DefaultPetFactory<TOwner, TPet> : IPetFactory<TOwner, TPet>
where TOwner : Owner
where TPet : Pet
{
// default implementation
}
If anyone has a better solution to this, preferably with the registrations it's appreciated. I don't like to change my classes to make the registration work.
(For the updated question)
There is a ticket in Windsor's issue tracker to support scenarios like that (feel free to vote for it), but in general this is something very hard to implement... generically (no pun intended), and as far as I know no container currently supports it.
In Windsor 3 you can workaround it by implementing a new interface called IGenericImplementationMatchingStrategy doing roughly the following (untested, I'm writing this from memory):
public class PetMatcher: IGenericImplementationMatchingStrategy
{
public Type[] GetGenericArguments(ComponentModel model, CreationContext context)
{
if (SomePreconditionToMakeSureThatsReallyTheScenarioDescribedAbove() == false )
{
return null;// which will fallback to default behaviour
}
// implementation needs just one generic arg, second of two the interface has
return new[]{ context.GenericArguments[1] };
}
}
You then register this as follows:
Container.Register(
Classes.FromAssemblyContaining(typeof(IPetFactory<,>)).BasedOn(typeof(IPetFactory<,>))
.WithServiceBase()
.Configure(
c => c.ExtendedProperties(
Property.ForKey(ComponentModel.GenericImplementationMatchingStrategy)
.Eq(new PetMatcher()))));
Can you import using a class that inherits from Lazy rather than Lazy itself? I am exporting using a derivitive of ExportAttribute that contains metadata.
[FeatureExport(/* Feature Metadata Parameters */)]
public class Feature : IFeature
{
// Feature Properties
}
public class FeatureReference : Lazy<IFeature, IFeatureMetadata>
{
}
public class Consumer
{
[ImportMany]
public IEnumerable<FeatureReference> FeatureReferences { get; set; }
}
Is this possible? Would it work? I could try it myself, but I'm in development so I don't actually have any code written.
No, it won't work I'm afraid. You would need to implement your own programming model extension (either a custom part/catalog or possibly via ReflectionModelServices) to make this work.
MEF would have to create the FeatureReference object in order to set it, and considering that FeatureReference might have any constructor imaginable, you can guess why this isn't supported.