Is there a way to add an extension to AnyObject? - protocols

In Objective-C, I created a very handy category (an extension, in Swift terms) of NSObject that added the ability to add arbitrary key/value pairs to any NSObject at runtime. It uses associated objects to attach a mutable dictionary to the object, and then provides get and set methods that get/set key/value pairs to/from that dictionary. It's only a few lines of code.
This makes it possible to attach arbitrary key/value pairs to ANY object at runtime, including objects created by the system. That's the key. There are cases where a system framework returns an object to you and you need to be able to attach a value to it.
This trick also makes it possible to create categories that have new instance variables. (Ok, they don't really, but for it does let you add new state variables to objects in a category.)
This isn't possible in Swift 1.2 because:
Swift doesn't have a base class for all objects like NSObject in
Objective-C. It uses AnyObject, which is a protocol.
Swift 1.2
doesn't allow extensions to protocols.
I had to give up on this under Swift 1.2.
But Swift 2 allows extensions to protocols. I thought "Great, now I can add my extension that lets me add key/value pairs to AnyObject!"
No joy.
When I try to create my extension for AnyObject:
extension AnyObject: AssociatedObjectProtocol
I get the error message
'AnyObject' Protocol cannot be extended
Arghh! So close, but nope. It seems like the language explicitly forbids extending AnyObject. Why is this, and is there any way around it?
I don't use my category on NSObject that often, but when I do, it's a lifesaver. I'd like to add it to my bag of tricks in Swift.
I could add it to NSObject just like I do in Objective-C, but that means it only works for objects that inherit from NSObject - making it not work for native Swift classes.

Unfortunately a workaround which does exactly the same as you want doesn't exist. So I would suggest to make a protocol which has an extension to add default implementations:
protocol A: AnyObject {}
// in Swift you would rather use this
protocol A: class {}
// add default implementations
extension A {
func aMethod() {
// code
}
}
// Example
class B: A {}
// use the method
B().aMethod()
This approach does not make all classes automatically conform to this protocol (but only classes can conform to it). So you have to make them conform yourself. Since you don't use this as much this would be a reasonable solution.

Along the lines of #Qbyte's answer, declaring that NSObject conforms to a protocol means that almost every class in the entire Cocoa/UIKit/Foundation universe will inherit that functionality:
protocol MyProtocol {
func doSomething()
}
extension MyProtocol {
func doSomething() {
print("This is me, doing something.")
}
}
extension NSObject: MyProtocol { }
You've just conformed 99% of Apple's framework classes to MyProtocol. You can make your own classes conform to MyProtocol by inheriting from NSObject or by simply conforming to it.

I feel like you had the answer in front of you. Extending NSObject works perfectly in Swift too. (Maybe not 6 years before tho 🥲)
extension NSObject { }

Related

Create Map of classes in TypeScript

I've got a rendering engine, much like React where I need to store classes rather than instances in an object for compiling.
So for example, I have a Button component that I would like to be able to dynamically instantiate. Doing this would be as easy as
new components["Button"]
For this, I need a list of all possible classes. So I've got a Dictionary interface declared like so:
interface Dictionary<T> {
[Key: string]: T;
}
This works well, I'm easily able to add objects to this dictionary. Except if I have an object:
const components: Dictionary<Component> = {
Button: Button
}
Then I get an error because Button is a class, rather than an instance. Here, the issue is, I don't want to define the dictionary as Dictionary<Function> because that would mean I allow any function into the dictionary. Specifically, I only want to allow classes into the dictionary that extend the Component class.
How would I achieve this?
You also need to define the signature of the constructor (which makes sense if you think about it), but you do the following:
interface ComponentClass {
new (a: number): Component;
}
(The signature of the constructor is probably not "number", but put in whatever it is.)

Intellij idea gdsl. Add constructor to the class. Documentation for GDSL

I have an annotation which adds some methods and default constructor to annotated class.
I have managed to create a gdsl, to enable autocompletion in idea for methods, but I'm stuck with constructor and documentation is very poor.
Does anyone have any ideas, how to do this?
Maybe I could find a solution, in existing gdsl, but I can't remember any Transformation, related to constructors. Maybe you can remind me of any of them.
def objectContext = context(ctype: "java.lang.Object")
contributor(objectContext) {
if (hasAnnotation("com.xseagullx.SomeAnnotation")) {
// Here I want to add constructor's declaration(with empty arg's)
// …
// And then my methods.
method name: 'someMethod', type: 'void', params: [:]
}
}
EDITED: OK, if it's as #jasp say, and there is no DSL construct for declaring Constructors, I'm still asking for a good documentation sources, other than JB's confluence page. Tutorials and other sources. I'm familiar with embedded dsl's for groovy, grails and gradle.
Need smth. more structured, if it's possible.
All function invocations inside of GroovyDSL are just calls to wrappers around internal IDEA's Program Structure Interface (PCI). However it doesn't cover all of PCI's abilities, including default constructors functionality I believe. One of an evidence for that is singletonTransform.gdsl, which is bundled into IDEA from 9 version and describes #Singleton AST transformation. Here is it's code:
contributor(context()) {
if (classType?.hasAnnotation("groovy.lang.Singleton")) {
property name: "instance",
type: classType?.getQualifiedName() ?: "java.lang.Object",
isStatic: true
}
}
As you can see it doesn't change a constructor and it's visibility, so IDEA will autocomplete this invalid code:
#Singleton class Foo {}
def foo = new Foo()
Futhermore GDSL that describes the semantics of GroovyDSL (which is actually the part of /plugins/groovy/resources/standardDsls/metaDsl.gdsl of IDEA sources) doesn't provide any ability for describing of constructors.
In this case I suggest you use newify transformation which allows you to describe targetClass.name method returning created instance.
I know this is a bit old, but I found myself looking for something similar.
The DSL you are looking for is
method params: [:], constructor: true although I don't understand why you'd need it; if a class doesn't declare any constructors doesn't IDEA always suggest the default one?

Metaprogramming: adding equals(Object o) and hashCode() to a library class

I have a library of domain objects which need to be used in the project, however we've found a couple of the classes haven't got an equals or hashCode method implemented.
I'm looking for the simplest (and Grooviest) way to add those methods. Obviously I could create a subclass which only adds the methods, but this would be confusing for developers used to the library and would mean we'd have to refactor existing code.
It is not possible to get the source changed (currently).
If I could edit the class I would just use the #EqualsAndHashCode annotation to carry out an AST transformation (at compile time?), but I can't find a way to instruct the compiler to carry out the transformation on a class which I can't directly annotate.
I'm currently trying to work up an example using the ExpandoMetaClass, so I'd do something like:
MySuperClass.metaClass.hashCode = { ->
// Add dynamic hashCode calculation bits here
}
MySuperClass.metaClass.equals = { ->
// Add dynamic hashCode calculation bits here
}
I don't really want to hand-code the hashCode/equals methods for each class, so I'm looking for something dyamic (like #EqualsAndHashCode) which will work with this.
Am I on the right track? Is there a groovier way?
AST Transforms are only applied at compile time, so you'll get no help from the likes of #EqualsAndHashCode. MetaClass hacks are going to be your only option. That said, there are more-elegant ways to impose MetaClass behavior.
Shameless Self Plug I did a talk about this kind of stuff last year at SpringOne 2GX: http://www.infoq.com/presentations/groovy-app-architecture
In short, you might find benefit in creating extensions (unless you're in Grails) - http://mrhaki.blogspot.com/2013/01/groovy-goodness-adding-extra-methods.html, or by explicitly adding mixins - http://groovy.codehaus.org/Runtime+mixins ... But in general, these are just cleaner ways to do the exact same thing you're already doing.

ServiceStack: RESTful Resource Versioning

I've taken a read to the Advantages of message based web services article and am wondering if there is there a recommended style/practice to versioning Restful resources in ServiceStack? The different versions could render different responses or have different input parameters in the Request DTO.
I'm leaning toward a URL type versioning (i.e /v1/movies/{Id}), but I have seen other practices that set the version in the HTTP headers (i.e Content-Type: application/vnd.company.myapp-v2).
I'm hoping a way that works with the metadata page but not so much a requirement as I've noticed simply using folder structure/ namespacing works fine when rendering routes.
For example (this doesn't render right in the metadata page but performs properly if you know the direct route/url)
/v1/movies/{id}
/v1.1/movies/{id}
Code
namespace Samples.Movies.Operations.v1_1
{
[Route("/v1.1/Movies", "GET")]
public class Movies
{
...
}
}
namespace Samples.Movies.Operations.v1
{
[Route("/v1/Movies", "GET")]
public class Movies
{
...
}
}
and corresponding services...
public class MovieService: ServiceBase<Samples.Movies.Operations.v1.Movies>
{
protected override object Run(Samples.Movies.Operations.v1.Movies request)
{
...
}
}
public class MovieService: ServiceBase<Samples.Movies.Operations.v1_1.Movies>
{
protected override object Run(Samples.Movies.Operations.v1_1.Movies request)
{
...
}
}
Try to evolve (not re-implement) existing services
For versioning, you are going to be in for a world of hurt if you try to maintain different static types for different version endpoints. We initially started down this route but as soon as you start to support your first version the development effort to maintain multiple versions of the same service explodes as you will need to either maintain manual mapping of different types which easily leaks out into having to maintain multiple parallel implementations, each coupled to a different versions type - a massive violation of DRY. This is less of an issue for dynamic languages where the same models can easily be re-used by different versions.
Take advantage of built-in versioning in serializers
My recommendation is not to explicitly version but take advantage of the versioning capabilities inside the serialization formats.
E.g: you generally don't need to worry about versioning with JSON clients as the versioning capabilities of the JSON and JSV Serializers are much more resilient.
Enhance your existing services defensively
With XML and DataContract's you can freely add and remove fields without making a breaking change. If you add IExtensibleDataObject to your response DTO's you also have a potential to access data that's not defined on the DTO. My approach to versioning is to program defensively so not to introduce a breaking change, you can verify this is the case with Integration tests using old DTOs. Here are some tips I follow:
Never change the type of an existing property - If you need it to be a different type add another property and use the old/existing one to determine the version
Program defensively realize what properties don't exist with older clients so don't make them mandatory.
Keep a single global namespace (only relevant for XML/SOAP endpoints)
I do this by using the [assembly] attribute in the AssemblyInfo.cs of each of your DTO projects:
[assembly: ContractNamespace("http://schemas.servicestack.net/types",
ClrNamespace = "MyServiceModel.DtoTypes")]
The assembly attribute saves you from manually specifying explicit namespaces on each DTO, i.e:
namespace MyServiceModel.DtoTypes {
[DataContract(Namespace="http://schemas.servicestack.net/types")]
public class Foo { .. }
}
If you want to use a different XML namespace than the default above you need to register it with:
SetConfig(new EndpointHostConfig {
WsdlServiceNamespace = "http://schemas.my.org/types"
});
Embedding Versioning in DTOs
Most of the time, if you program defensively and evolve your services gracefully you wont need to know exactly what version a specific client is using as you can infer it from the data that is populated. But in the rare cases your services needs to tweak the behavior based on the specific version of the client, you can embed version information in your DTOs.
With the first release of your DTOs you publish, you can happily create them without any thought of versioning.
class Foo {
string Name;
}
But maybe for some reason the Form/UI was changed and you no longer wanted the Client to use the ambiguous Name variable and you also wanted to track the specific version the client was using:
class Foo {
Foo() {
Version = 1;
}
int Version;
string Name;
string DisplayName;
int Age;
}
Later it was discussed in a Team meeting, DisplayName wasn't good enough and you should split them out into different fields:
class Foo {
Foo() {
Version = 2;
}
int Version;
string Name;
string DisplayName;
string FirstName;
string LastName;
DateTime? DateOfBirth;
}
So the current state is that you have 3 different client versions out, with existing calls that look like:
v1 Release:
client.Post(new Foo { Name = "Foo Bar" });
v2 Release:
client.Post(new Foo { Name="Bar", DisplayName="Foo Bar", Age=18 });
v3 Release:
client.Post(new Foo { FirstName = "Foo", LastName = "Bar",
DateOfBirth = new DateTime(1994, 01, 01) });
You can continue to handle these different versions in the same implementation (which will be using the latest v3 version of the DTOs) e.g:
class FooService : Service {
public object Post(Foo request) {
//v1:
request.Version == 0
request.Name == "Foo"
request.DisplayName == null
request.Age = 0
request.DateOfBirth = null
//v2:
request.Version == 2
request.Name == null
request.DisplayName == "Foo Bar"
request.Age = 18
request.DateOfBirth = null
//v3:
request.Version == 3
request.Name == null
request.DisplayName == null
request.FirstName == "Foo"
request.LastName == "Bar"
request.Age = 0
request.DateOfBirth = new DateTime(1994, 01, 01)
}
}
Framing the Problem
The API is the part of your system that exposes its expression. It defines the concepts and the semantics of communicating in your domain. The problem comes when you want to change what can be expressed or how it can be expressed.
There can be differences in both the method of expression and what is being expressed. The first problem tends to be differences in tokens (first and last name instead of name). The second problem is expressing different things (the ability to rename oneself).
A long-term versioning solution will need to solve both of these challenges.
Evolving an API
Evolving a service by changing the resource types is a type of implicit versioning. It uses the construction of the object to determine behavior. Its works best when there are only minor changes to the method of expression (like the names). It does not work well for more complex changes to the method of expression or changes to the change of expressiveness. Code tends to be scatter throughout.
Specific Versioning
When changes become more complex it is important to keep the logic for each version separate. Even in mythz example, he segregated the code for each version. However, the code is still mixed together in the same methods. It is very easy for code for the different versions to start collapsing on each other and it is likely to spread out. Getting rid of support for a previous version can be difficult.
Additionally, you will need to keep your old code in sync to any changes in its dependencies. If a database changes, the code supporting the old model will also need to change.
A Better Way
The best way I've found is to tackle the expression problem directly. Each time a new version of the API is released, it will be implemented on top of the new layer. This is generally easy because changes are small.
It really shines in two ways: first all the code to handle the mapping is in one spot so it is easy to understand or remove later and second it doesn't require maintenance as new APIs are developed (the Russian doll model).
The problem is when the new API is less expressive than the old API. This is a problem that will need to be solved no matter what the solution is for keeping the old version around. It just becomes clear that there is a problem and what the solution for that problem is.
The example from mythz's example in this style is:
namespace APIv3 {
class FooService : RestServiceBase<Foo> {
public object OnPost(Foo request) {
var data = repository.getData()
request.FirstName == data.firstName
request.LastName == data.lastName
request.DateOfBirth = data.dateOfBirth
}
}
}
namespace APIv2 {
class FooService : RestServiceBase<Foo> {
public object OnPost(Foo request) {
var v3Request = APIv3.FooService.OnPost(request)
request.DisplayName == v3Request.FirstName + " " + v3Request.LastName
request.Age = (new DateTime() - v3Request.DateOfBirth).years
}
}
}
namespace APIv1 {
class FooService : RestServiceBase<Foo> {
public object OnPost(Foo request) {
var v2Request = APIv2.FooService.OnPost(request)
request.Name == v2Request.DisplayName
}
}
}
Each exposed object is clear. The same mapping code still needs to be written in both styles, but in the separated style, only the mapping relevant to a type needs to be written. There is no need to explicitly map code that doesn't apply (which is just another potential source of error). The dependency of previous APIs is static when you add future APIs or change the dependency of the API layer. For example, if the data source changes then only the most recent API (version 3) needs to change in this style. In the combined style, you would need to code the changes for each of the APIs supported.
One concern in the comments was the addition of types to the code base. This is not a problem because these types are exposed externally. Providing the types explicitly in the code base makes them easy to discover and isolate in testing. It is much better for maintainability to be clear. Another benefit is that this method does not produce additional logic, but only adds additional types.
I am also trying to come with a solution for this and was thinking of doing something like the below. (Based on a lot of Googlling and StackOverflow querying so this is built on the shoulders of many others.)
First up, I don’t want to debate if the version should be in the URI or Request Header. There are pros/cons for both approaches so I think each of us need to use what meets our requirements best.
This is about how to design/architecture the Java Message Objects and the Resource Implementation classes.
So let’s get to it.
I would approach this in two steps. Minor Changes (e.g. 1.0 to 1.1) and Major Changes (e.g 1.1 to 2.0)
Approach for minor changes
So let’s say we go by the same example classes used by #mythz
Initially we have
class Foo { string Name; }
We provide access to this resource as /V1.0/fooresource/{id}
In my use case, I use JAX-RS,
#Path("/{versionid}/fooresource")
public class FooResource {
#GET
#Path( "/{id}" )
public Foo getFoo (#PathParam("versionid") String versionid, (#PathParam("id") String fooId)
{
Foo foo = new Foo();
//setters, load data from persistence, handle business logic etc
Return foo;
}
}
Now let’s say we add 2 additional properties to Foo.
class Foo {
string Name;
string DisplayName;
int Age;
}
What I do at this point is annotate the properties with a #Version annotation
class Foo {
#Version(“V1.0")string Name;
#Version(“V1.1")string DisplayName;
#Version(“V1.1")int Age;
}
Then I have a response filter that will based on the requested version, return back to the user only the properties that match that version. Note that for convenience, if there are properties that should be returned for all versions, then you just don’t annotate it and the filter will return it irrespective of the requested version
This is sort of like a mediation layer. What I have explained is a simplistic version and it can get very complicated but hope you get the idea.
Approach for Major Version
Now this can get quite complicated when there is a lot of changes been done from one version to another. That is when we need to move to 2nd option.
Option 2 is essentially to branch off the codebase and then do the changes on that code base and host both versions on different contexts. At this point we might have to refactor the code base a bit to remove version mediation complexity introduced in Approach one (i.e. make the code cleaner) This might mainly be in the filters.
Note that this is just want I am thinking and haven’t implemented it as yet and wonder if this is a good idea.
Also I was wondering if there are good mediation engines/ESB’s that could do this type of transformation without having to use filters but haven’t seen any that is as simple as using a filter. Maybe I haven’t searched enough.
Interested in knowing thoughts of others and if this solution will address the original question.

Trying to understand IOC and binding

I am very new to concept of IOC and I understand the fact that they help us resolve different classes in different contexts. Your calling class will just interact with Interface and Interface with decide which implementation to give you and it takes care of newing up the object.
Please do correct me if I am understanding is wrong because my question is based on that:
Now, I see this pattern very often in these projects:
private readonly IEmailService emailService;
private readonly ITemplateRenderer templateRenderer;
private readonly IHtmlToTextTransformer htmlToTextTransformer;
public TemplateEmailService(IEmailService emailService,
ITemplateRenderer templateRenderer,
IHtmlToTextTransformer htmlToTextTransformer)
{
this.emailService = emailService;
this.htmlToTextTransformer = htmlToTextTransformer;
this.templateRenderer = templateRenderer;
}
I understand that this helps using all the implementations of these classes without newing them up and also you don't have to decide WHICH implementaion to get, your IOC decides it for you, right?
but when I code like this, I do not even touch any IOC congiguration files. And again I am usin git for 2 days only but from all the tutorials that I have read, I was expecting my self to configure something which says "Resolve IParent to Child" class. But it works without me doing anything like it. Is it because there is only one implementaion of these interfaces? and If I do have more than one implementations then and then only I will have to configure resolved explicitly?
The code sample you have is a case of Constructor Injection.
In a traditional code, you would have a parameterless constructor, and in it you would "new-up" your objects like this:
IEmailService emailService = new EmailService();
So your code is explictly controlling which implementation gets assigned to the interface variable.
In IoC using constructor injection, control is inverted, meaning the container is "driving the bus" and is creating your TemplateEmailService object. When it is about to create it, the container looks at your constructor parameters (IEmailService , ITemplateRenderer , etc.) and feeds those objects to your class for use.
The IoC container can be configured so that interface A gets fulfilled by implementation B (or C) explicitly. Each one has a way to do it. Or it could do it by convention (IFoo fulfilled by Foo), or even attributes in classes, whatever.
So to answer your question-- you can explicitly define which implementations get used to fulfill certain interfaces. Got to read the IoC container docs for how to.
One more thing - "when you code like this", you technically don't have to be using an IoC container. In fact, your class should not have a direct reference to the container - it will maximize the reusability, and also allow easy testing. So you would wire-up interfaces to implementation classes elsewhere.

Resources