Background
I'm developing a Spring Boot application and I'm using Kotlin, IntelliJ and Gradle (Groovy). I have some enum class in my code and I need to persist them (with JPA). I used a simple global converter.
// Sample Enum
enum class Policy {
PUBLIC,
INVITE_ONLY
}
// Sample Converter
#Converter(autoApply = true)
class PolicyConverter : AttributeConverter<Policy, String> {
override fun convertToDatabaseColumn(attribute: Policy): String {
return attribute.name
}
override fun convertToEntityAttribute(dbData: String): Policy {
return Policy.valueOf(dbData.toUpperCase())
}
}
Problem
Since I have 5-6 enums and I hate duplicated code, I thought about a generic converter that should do the work for every given enum. I tried to code something, but nothing worked. This is what I was thinking about:
abstract class EnumConverter<E: Enum<E>> : AttributeConverter<E, String> {
override fun convertToDatabaseColumn(attribute: E): String {
return attribute.name
}
override fun convertToEntityAttribute(dbData: String): E {
return E.valueOf(dbData.toUpperCase())
}
}
In this way I can only extend from one abstract class every enum converter, like so:
#Converter(autoApply = true)
class PolicyConverter : EnumConverter<Policy>() {}
Problem with this code is that I have two errors:
E is red because: Type parameter 'E' cannot have or inherit a companion object, so it cannot be on the left hand side of dot
valueOf is red because: unresolved reference (there are like 150+ types of .valueOf).
As suggested from this I tried to use following function:
private inline fun <reified E : Enum<E>> getValue(string: String): E {
return enumValueOf(string.toUpperCase())
}
But when called from the .convertToEntityAttribute, the result is that "Cannot use 'E' as reified type parameter. Use a class instead."
Question
So the question is simple: how can I implement an easy and fast way to make one converter for all my enums, that all follows the same principle? I just need a return E.valueOf(<value>) function, but it's not present.
A simply workaround of this problem is to define an abstract method that every class will implement and it will return the correct type, given a string.
// Inside EnumConverter, the Generic Class
abstract class EnumConverter<E: Enum<E>> : AttributeConverter<E, String> {
abstract fun getValueFromString(string: String) : E
override fun convertToEntityAttribute(dbData: String): E {
return getValueFromString(dbData)
}
[...]
}
// Inside Policy Enum, implementing
class PolicyConverter : EnumConverter<Policy>() {
override fun getValueFromString(string: String): Policy {
return Policy.valueOf(string.toUpperCase())
}
}
But it's a workaround that I really dislike.
After upgrading to ReSharper 10 the following error is shown but it builds without any error.
Class 'BaseTourModule' cannot extend class 'BaseModule': Types of property 'settings' of types 'BaseModule' and 'BaseTourModule' are incompatible
Type parameter 'TSetup' constraint isn't related to 'TSetup'
Type parameter 'TSetup' is incompatible with 'BaseTourModuleSetup', which is not type parameter
Whereas BaseModule is defined as
export abstract class BaseModule<TSetup extends BaseModuleSetup> {
protected settings: TSetup;
}
and BaseModuleSetup
export abstract class BaseModuleSetup {
protected translations: { [index: string]: string; } = {};
abstract isValid(): boolean;
}
The concrete implementation of BaseTourModule (where the error is thrown) is:
export abstract class BaseTourModule<TSetup extends BaseTourModuleSetup> extends BaseModule<TSetup> {
}
Last, but not least, this is the implementation of BaseTourModuleSetup
export abstract class BaseTourModuleSetup extends BaseModuleSetup {
}
I'm using Visual Studio 2015 Professsional and the project is building against ECMAScript 5 using TypeScript 1.6. Is this an error by ReSharper or is there something wrong which I don't see?
That's a bug in ReSharper 10.0. Is already fixed for bugfix update 10.0.1, which will be released relatively soon.
Looks like you used casting in your inheritance, and from what I understood, it should look like this:
export abstract class BaseModuleSetup {
protected translations: { [index: string]: string; } = {};
abstract isValid(): boolean;
}
export abstract class BaseModule extends BaseModuleSetup {
protected settings: TSetup;
}
export abstract class BaseTourModuleSetup extends BaseModuleSetup {
}
export abstract class BaseTourModule extends BaseTourModuleSetup {
}
Anyways, (Without really knowing what your are trying to achieve) it looks like your are over complicating this with class hierarchy.
If you want, you can explain what are your goals and we can build the best class diagram for your needs.
For the following class:
module LayoutEngine {
enum DocumentFormat {
DOCX = 1
};
export class DocHeader {
public format : DocumentFormat;
}
}
I have two questions:
The above has a compile error where it says "Public property
'format' of exported class has or is using private type
'DocumentFormat'." but a declaration of public before the enum is
also an error. So how do I do this?
Is there a way to place the enum declaration inside the class? Just a module name isn't great for namespacing as I have a lot of classes in that module.
thanks - dave
The above has a compile error where it says "Public property 'format' of exported class has or is using private type 'DocumentFormat'.
Simply export :
module LayoutEngine {
export enum DocumentFormat {
DOCX = 1
};
export class DocHeader {
public format : DocumentFormat;
}
}
Is there a way to place the enum declaration inside the class?
the enum typescript type needs to be at a module level (a file or inside a module). Of course if you want it inside the class just use a json object
module LayoutEngine {
export class DocHeader {
DocumentFormat = {
DOCX: 1
};
public format : number;
}
}
I'm looking into the possibilities to do TDD with TypeScript.
If I write my tests in TypeScript, is it possible to make the import statements return mocks for my class under test?
Or is the only feasible approach to write the tests in pure javascript and deal with injecting AMDs myself?
I have developed an IoC container called InversifyJS with advanced dependency injection features like contextual bindings.
You need to follow 3 basic steps to use it:
1. Add annotations
The annotation API is based on Angular 2.0:
import { injectable, inject } from "inversify";
#injectable()
class Katana implements IKatana {
public hit() {
return "cut!";
}
}
#injectable()
class Shuriken implements IShuriken {
public throw() {
return "hit!";
}
}
#injectable()
class Ninja implements INinja {
private _katana: IKatana;
private _shuriken: IShuriken;
public constructor(
#inject("IKatana") katana: IKatana,
#inject("IShuriken") shuriken: IShuriken
) {
this._katana = katana;
this._shuriken = shuriken;
}
public fight() { return this._katana.hit(); };
public sneak() { return this._shuriken.throw(); };
}
2. Declare bindings
The binding API is based on Ninject:
import { Kernel } from "inversify";
import { Ninja } from "./entities/ninja";
import { Katana } from "./entities/katana";
import { Shuriken} from "./entities/shuriken";
var kernel = new Kernel();
kernel.bind<INinja>("INinja").to(Ninja);
kernel.bind<IKatana>("IKatana").to(Katana);
kernel.bind<IShuriken>("IShuriken").to(Shuriken);
export default kernel;
3. Resolve dependencies
The resolution API is based on Ninject:
import kernel = from "./inversify.config";
var ninja = kernel.get<INinja>("INinja");
expect(ninja.fight()).eql("cut!"); // true
expect(ninja.sneak()).eql("hit!"); // true
The latest release (2.0.0) supports many use cases:
Kernel modules
Kernel middleware
Use classes, string literals or Symbols as dependency identifiers
Injection of constant values
Injection of class constructors
Injection of factories
Auto factory
Injection of providers (async factory)
Activation handlers (used to inject proxies)
Multi injections
Tagged bindings
Custom tag decorators
Named bindings
Contextual bindings
Friendly exceptions (e.g. Circular dependencies)
You can learn more about it at https://github.com/inversify/InversifyJS
I use infuse.js for Dependency Injection in TypeScript.
Reference the d.ts
/// <reference path="definition/infusejs/infusejs.d.ts"/>
Initialize your injector at startup
this.injector = new infuse.Injector();
Map Dependencies
this.injector.mapClass( 'TodoController', TodoController );
this.injector.mapClass( 'TodoView', TodoView );
this.injector.mapClass( 'TodoModel', TodoModel, true ); // 'true' Map as singleton
Inject Dependencies
export class TodoController
{
static inject = ['TodoView', 'TodoModel'];
constructor( todoView:TodoView, todoModel:TodoModel )
{
}
}
It's string based as opposed to being type based (as reflection isn't yet possible in TypeScript). Despite that, it works very well in my applications.
Try this Dependency Injector (Typejector)
GitHub Typejector
With new TypeScript 1.5 it is possible using annotation way
For example
#injection
class SingletonClass {
public cat: string = "Kitty";
public dog: string = "Hot";
public say() {
alert(`${this.cat}-Cat and ${this.dog}-Dog`);
}
}
#injection
class SimpleClass {
public say(something: string) {
alert(`You said ${something}?`);
}
}
#resolve
class NeedInjectionsClass {
#inject(SingletonClass)
public helper: SingletonClass;
#inject(SimpleClass)
public simpleHelper: SimpleClass;
constructor() {
this.helper.say();
this.simpleHelper.say("wow");
}
}
class ChildClass extends NeedInjectionsClass {
}
var needInjection = new ChildClass();
For question case:
some property should realise pseudo Interface (or abstract class) like in next example.
class InterfaceClass {
public cat: string;
public dog: string;
public say() {
}
}
#injection(true, InterfaceClass)
class SingletonClass extends InterfaceClass {
public cat: string = "Kitty";
public dog: string = "Hot";
public say() {
alert(`${this.cat}-Cat and ${this.dog}-Dog`);
}
}
#injection(true, InterfaceClass)
class MockInterfaceClass extends InterfaceClass {
public cat: string = "Kitty";
public dog: string = "Hot";
public say() {
alert(`Mock-${this.cat}-Cat and Mock-${this.dog}-Dog`);
}
}
#injection
class SimpleClass {
public say(something: string) {
alert(`You said ${something}?`);
}
}
#resolve
class NeedInjectionsClass {
#inject(InterfaceClass)
public helper: InterfaceClass;
#inject(SimpleClass)
public simpleHelper: SimpleClass;
constructor() {
this.helper.say();
this.simpleHelper.say("wow");
}
}
class ChildClass extends NeedInjectionsClass {
}
var needInjection = new ChildClass();
Note: Mock injection should define after source code, because it mast redefine class-creator for interface
For people who use Angular2 I have developed Fluency Injection https://www.npmjs.com/package/fluency-injection. The documentation is quite complete and it mimics the behaviour of Angular2's DI.
Feedback is much appreciated and I hope it helps you :)
You can use the solution:
Lightweight dependency injection container for JavaScript/TypeScript
import {autoInjectable, container} from "tsyringe";
class MyService {
move(){
console.log('myService move 123', );
}
}
class MyServiceMock {
move(){
console.log('mock myService move 777', );
}
}
#autoInjectable()
export class ClassA {
constructor(public service?: MyService) {
}
move(){
this.service?.move();
}
}
container.register(MyService, {
useClass: MyServiceMock
});
new ClassA().move();
output:
mock myService move 777
I've been developing a DI solution called Pigly. An example given the original question regarding injecting and testing (admittedly not automatic-mock generation - although you could try ts-auto-mock as I've done here):
Given:
interface IDb {
set(key: string, value: string);
}
interface IApi {
setName(name: string);
}
class Api implements IApi {
constructor(private db: IDb) {}
setName(name: string){
this.db.set("name", name);
}
}
We can bind the types with,
import { Kernel, toSelf, to, toConst } from 'pigly';
import * as sinon from 'sinon';
let spy = sinon.spy();
let kernel = new Kernel();
kernel.bind(toSelf(Api));
kernel.bind<IApi>(to<Api>());
kernel.bind<IDb>(toConst({ set: spy }));
then resolve and test with:
let api = kernel.get<IApi>();
api.setName("John");
console.log(spy.calledWith("name", "John"));
execution/compilation of this example requires a typescript transformer - to compile the interface-symbols and constructor provider into plain javascript. There are a few ways to do this. The ts-node + ttypescript approach is to have a tsconfig.json:
{
"compilerOptions": {
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"plugins": [{
"transform": "#pigly/transformer"
}]
}
}
and execute with
ts-node --compiler ttypescript example-mock.ts
Pigly has the distinction of not requiring any changes to your (or third-party) classes, at the expense of either the use of a typescript transformer, or more verbose binding if (you don't want to use the transformer). Its still experimental, but I think it shows promise.
TypeScript works well with AMD loaders like requirejs. If confgured properly, TypeScript will output fully AMD compliant javascript.
In a testing situation, you could configure requirejs to inject testable modules.
You can give this a shot: https://www.npmjs.com/package/easy-injectionjs. It is a generic use dependency injection package.
#EasySingleton creates a single instance of the dependency through the entire application. It is ideal for a service of some sort.
#EasyPrototype creates as many instances of the dependency as needed. It is ideal for changeable dependencies.
#EasyFactory is primarily used for inheritance:
You can do anything using this package:
Simple usage (Coming from the readme):
import { Easy, EasyFactory, EasyPrototype, EasySingleton } from 'easy-injectionjs';
#EasyFactory()
abstract class Person {
abstract getName();
abstract setName(v: string);
}
// #EasyObservable()
#EasySingleton()
class Somebody extends Person{
// #Easy()
constructor (private name: string) {
super()
this.name = 'Sal';
}
public getName() {
return this.name;
}
public setName(v: string) {
this.name = v;
}
}
#EasyPrototype()
class Nobody extends Person{
#Easy()
somebody: Person;
constructor () {
super()
}
public getName() {
return this.somebody.getName();
}
public setName(v: string) {
this.somebody.setName(v);
}
}
#EasyPrototype()
class Data {
#Easy()
somebody: Person;
name: string;
change(v: string) {
this.somebody.setName(v);
}
getName(): string {
return this.somebody.getName();
}
}
let n = new Nobody();
console.log(n.getName()) // Prints Sal
n.setName('awesome');
console.log(n.getName()) // Prints awesome
let d = new Data()
console.log(d.getName()) // Prints awesome
d.change('Gelba')
console.log(n.getName()) // Prints Gelba
d.change('kaa')
console.log(n.getName()) // Prints Kaa
Even if you want to inject node modules you can do this:
import * as IExpress from 'express';
import { Easy, EasySingleton } from 'easy-injectionjs';
#EasySingleton()
class Express extends IExpress {}
#EasySingleton()
export class App {
#Easy()
private _express: Express;
}
let app = new App();
console.log(app)
Of course, the usage of the express server isn't for console logging. It is just for testing :D.
Hope that helps :D
Dime is a very simple dependency injection library. It's very early into development, though, so it probably has some bugs. There is more information on the wiki page.
Example usage:
import { ItemsService } from './items-service'; // ItemsService is an interface
import { Inject } from '#coined/dime';
class ItemsWidget {
#Inject()
private itemsService: ItemsService;
render() {
this.itemsService.getItems().subscribe(items => {
// ...
});
}
}
// Setup
const appPackage = new Package("App", {
token: "itemsService",
provideClass: AmazonItemsService // AmazonItemsService implements ItemsService
});
Dime.mountPackages(appPackage);
// Display the widget
const widget = new ItemsWidget();
widget.render();
I work on AutoFixtureTS that is inspired by AutoFixture. AutoFixtureTS makes it easier for TypeScript developers to do Test-Driven Development by automating non-relevant Test Fixture Setup, allowing the Test Developer to focus on the essentials of each test case.
http://ronniehegelund.github.io/AutoFixtureTS/
Its still just prototype code, but check it out :-)
/ronnie
Sorry for the vague title, but I'm not sure what this is called.
Say I add IDisposable to my class, Visual Studio can create the method stub for me. But it creates the stub like:
void IDisposable.Dispose()
I don't follow what this syntax is doing. Why do it like this instead of public void Dispose()?
And with the first syntax, I couldn't work out how to call Dispose() from within my class (in my destructor).
When you implement an interface member explicitly, which is what the generated code is doing, you can't access the member through the class instance. Instead you have to call it through an instance of the interface. For example:
class MyClass : IDisposable
{
void IDisposable.Dispose()
{
// Do Stuff
}
~MyClass()
{
IDisposable me = (IDisposable)this;
me.Dispose();
}
}
This enables you to implement two interfaces with a member of the same name and explicitly call either member independently.
interface IExplict1
{
string InterfaceName();
}
interface IExplict2
{
string InterfaceName();
}
class MyClass : IExplict1, IExplict2
{
string IExplict1.InterfaceName()
{
return "IExplicit1";
}
string IExplict2.InterfaceName()
{
return "IExplicit2";
}
}
public static void Main()
{
MyClass myInstance = new MyClass();
Console.WriteLine( ((IExplcit1)myInstance).InstanceName() ); // outputs "IExplicit1"
IExplicit2 myExplicit2Instance = (IExplicit2)myInstance;
Console.WriteLine( myExplicit2Instance.InstanceName() ); // outputs "IExplicit2"
}
Visual studio gives you two options:
Implement
Implement explicit
You normally choose the first one (non-explicit): which gives you the behaviour you want.
The "explicit" option is useful if you inherit the same method from two different interfaces, i.e multiple inheritance (which isn't usually).
Members of an interface type are always public. Which requires their method implementation to be public as well. This doesn't compile for example:
interface IFoo { void Bar(); }
class Baz : IFoo {
private void Bar() { } // CS0737
}
Explicit interface implementation provides a syntax that allows the method to be private:
class Baz : IFoo {
void IFoo.Bar() { } // No error
}
A classic use for this is to hide the implementation of a base interface type. IEnumerable<> would be a very good example:
class Baz : IEnumerable<Foo> {
public IEnumerator<Foo> GetEnumerator() {}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { }
}
Note how the generic version is accessible, the non-generic version is hidden. That both discourages its use and avoids a compile error because of a duplicate method.
In your case, implementing Dispose() explicitly is wrong. You wrote Dispose() to allow the client code to call it, forcing it to cast to IDisposable to make the call doesn't make sense.
Also, calling Dispose() from a finalizer is a code smell. The standard pattern is to add a protected Dispose(bool disposing) method to your class.