How to match a class with annotation inside? - byte-buddy

I have an annotation named Metric
#Target({ElementType.FIELD, ElementType.METHOD})
public #interface Metric {
String name() default "";
}
I want to weave some logic when some methods with the #Metric annotation, like:
public class MethodWithMetricDemo{
#Metric
public void targetMethod(){
// do some thing
}
}
But how to match the class MethodWithMetricDemo in new AgentBuilder.Default().type(xxxxxxxxxxxxxxxx) ?

You would need to match your type based on the method annotatation. As methods are inherited virtually, you would however need to travers the entire class hierarchy by hasSuperType(declaresMethod(isAnnotatedWith(...))). This is possible but rather expensive. If you choose to use such a matcher, you should probably restrict your matching to a given namespace.

Related

DDD ValueObject and Enumeration , is there any good way to implement serialization?

In DDD, Value Object and Enumeration are quite beautiful so that I want use both two in the daily program logic, not only domain logic. When use customized value objects and enumerations, serialization problem is coming : should I implemented all the value objects and enumeration with System.Text.Json.JsonConverter<T> , or is there any good way to handle serialization and deserialization ?
Update:
to make it clear, Eumeration demo as below(ValueObject derived classes are same.):
[JsonConverter(typeof(CustomizedConverter))]
public class CustomizedEnumeration1 : Enumeration
{
public string Customized { get; protected set; }
public ... // some other customized property or class
public CustomizedEnumeration(int id, string name, string customized) : base(id, string) {
Customized = customized;
}
}
public class Customized2 : Enumeration
{ ... }
public class OtherCustomized: Enumeration
{ ... }
In DDD, properties sometimes are sealed by protected/private setter, deserialization has no right to set the value. Many derived classes can't deserialize as expected, so we have to rewrite serialization with System.Text.Json.JsonConverter<T> one by one. rewrite every derived Enumeration / Valueobject converter is not good, can any one point out any easy abstraction for that ?
You can achieve your desired result. You need to switch to NewtonsoftJson serialization.
Call this in Startup.cs in the ConfigureServices method:
services.AddControllers().AddNewtonsoftJson();
After this, your constructor will be called by deserialization for classes with private setter.
There is no need for custom converters.
For reference, I am using ASP Net Core 3.1

Typescript Abstract Class Method Access Derived Class Property

abstract class MyClass() {
protected static foo: Array<number>;
protected static doWorkOnFoo(): void {
let x: number = 0;
for (let f of | what goes here? this? self?|.foo) {
x = x + foo;
}
}
}
When implementing an abstract class, and wanting derived classes to have a static property and a static method that operates on those properties, how would one access those in the abstract class so that the derived class can just use that method?
I know this can be worked around by just setting a default value on the static property and using this, but this sparked my interested and I'm curious to know if there's some way to access generic derived class or something from an abstract class in TS.
Thanks in advance!
EDIT:
While I wasn't able to find exactly what I was looking for (see comments), a workable solution is to change the signature of the doWorkOnFoo() method to the following:
protected static doWorkOnFoo(): (typeof MyClass) => void;
Since it is already an abstract class it can take a derived class as an argument and then reference the derived class's static properties.

Orika - how to map inheritance and flattening?

I have been struggling with a task how to tell Orika to map an inherited structure that is flattened to DTO so that it may correctly resolve the implementation on reconstruction of an object. Here is an example of a simple structure with many nested objects:
abstract class Document {
// common values
}
class LegalDocument extends Document {
// complex object with many nested objects
}
class PersonalDocument extends Document {
// complex object with many nested objects
}
And let's say I have a reason to have an object flattened of the structure above:
class FlattenedDocument {
private String documentType = "LEGAL"; // "LEGAL" or "PERSONAL"
// flattened properties of Document and both its subclasses
}
I am able to tell Orika via CustomMapper<Document, FlattenedDocument> to map correctly the property documentType with a correct value based on an actual type (class) of the input document, but what I don't know how to do is the reverse situation. I need to tell Orika that when it converts from FlattenedDocument to one of the implementations of abstract Document, whether it should create the former or the latter by the value of documentType property. I can do that via CustomConverter or ObjectFactory but in both cases I am losing the benefit of byDefault().
Is there any way how to use the standard ClassMap with byDefault() option
factory.classMap(Document.class, FlattenedDocument.class).byDefault().register();
but with the possibility to tell Orika that it should re-instantiate the object based on the value of documentType field?
Thanks.
You can create a CustomConverter, that decides the type based on your field:
public class ShapeReverseConverter extends CustomConverter<ShapeDTO, Shape> {
#Override
public Shape convert(ShapeDTO source, Type<? extends Shape> destinationType, MappingContext mappingContext) {
if (Circle.class.getSimpleName().equals(source.type)) {
return mapperFacade.map(source, Circle.class);
} else {
return mapperFacade.map(source, Rectangle.class);
}
}
}
In Config you can map setting the type:
DefaultMapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
mapperFactory.classMap(Shape.class, ShapeDTO.class).byDefault()
.field("class.simpleName", "type")
.register();
mapperFactory.getConverterFactory().registerConverter(new ShapeReverseConverter());

AOP - Injecting a property with a dynamically computed value

(or "Using LocationInterceptionAspect and IInstanceScopedAspect together")
Using Postsharp I'm trying to inject a property into a target class using 'IntroduceMember' and then using the 'OnGetValue' functionality of LocationInterceptionAspect dynamically give it a value on inspection.
Originally I thought that I'd need two separate aspects, one for the field injection and one for the location interception but managed to combine the two by implementing the IInstanceScopedAspect interface and inheriting from LocationInterceptionAspect.
The problem is that if I set a breakpoint I will see the property that's been injected, but if I set another breakpoint in the OnGetValue method (that gets fired for each property on the class) I can't see it...
Here's some sample code:
[Serializable]
class DALDecoratorWrapper : LocationInterceptionAspect, IInstanceScopedAspect
{
public override void OnGetValue(LocationInterceptionArgs args)
{
if (args.LocationName == "Type")
{
args.Value = "computed value here";
}
args.ProceedGetValue();
}
[IntroduceMember(OverrideAction = MemberOverrideAction.OverrideOrFail)]
public String Type { get; set; }
I was also hoping there was a better way of doing this than overriding OnGetValue as that's called for each getter where really I want to only target the getter of the property that's been injected
Cheers

how to design an interface for different object to using them in a builder design pattern?

I have at least two different classes like following :
//NOTE : these two classes have getter and setter also
class Artist {
String artistName;
String artistWebsite;
String artistDbpedia;
String artistImage;
List<String> astistAlbumsName;
List<String> astistAlbumsUrl;
}
class Venu {
String VenuName;
String VenuWebsite;
String VenuDbpdia;
String VenuImage;
String VenuDescription;
List<String> venuFans;
}
I want to have a producer class to get an xml file as an input and detect the type of xml (venu/artist) then start to create a product object based on the input.
the problem :
I want to create an interface for aggregate the similarity between above two classes so my interface would be:
interface Model {
public String getImage();
public String getName();
public String getWebsite();
public String getdbpedia();
}
Then I can implement this interface in my builder class and above two classes but how about those different methods?
such as getVenuFans / getArtistAlbumName / etc....?
How can I call them from my producer?
this is my builder :
Class Builder implements Model {
public String getImage(){}
public String getName(){}
public String getWebsite(){}
public String getdbpedia(){}
}
and this can be my producer :
Class Producer {
public Producer()
{
Builder b = null;
//assume Venu and Artist implements Model
b = (Builder) new Venu();
//I don't have access to getVenuFans()!
b = (Builder) new Artist();
//I don't have access to getArtistAlbumsName() / etc...
}
}
You don't have access to those methods because you're casting the objects to a Builder, and Builder doesn't have those methods.
I see what you're trying to do, but I don't think it will work. For example, getVenueFans (I'm assuming you mean venue) is only appropriate for the Venue class. It doesn't make sense to try and abstract that into an interface that other non-Venue classes will implement.
I think what you have is good: You've abstracted the common methods into an interface. To call the methods on Venue and Artist, the consuming code will need to cast the objects to the appropriate type, then call the methods on it. And that's not as bad as you might think. It's the consuming code that knows what type it's dealing with (otherwise, why would it be trying to call getVenueFans?), so that's the point where it makes sense to cast and call the method directly.