diff --git a/src/Context.php b/src/Context.php
new file mode 100644
index 0000000000000000000000000000000000000000..eeb6c3015c613b66dfbc962c3d2bc727f5dd1435
--- /dev/null
+++ b/src/Context.php
@@ -0,0 +1,128 @@
+<?php declare(strict_types=1);
+/*
+ * irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata.
+ * Copyright (C) 2018 IRSTEA
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License and the GNU
+ * Lesser General Public License along with this program. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+namespace Irstea\NgModelGeneratorBundle;
+
+/**
+ * Class Context.
+ */
+class Context implements ContextInterface
+{
+    /** @var string */
+    private $rootClass;
+
+    /** @var bool */
+    private $normalization;
+
+    /** @var string[] */
+    private $groups;
+
+    /** @var string[][] */
+    private $defaultGroups;
+
+    /**
+     * Context constructor.
+     *
+     * @param string      $rootClass
+     * @param bool        $normalization
+     * @param string[]    $groups
+     * @param \string[][] $defaultGroups
+     */
+    public function __construct(string $rootClass, array $defaultGroups, bool $normalization = false, array $groups = [])
+    {
+        $this->rootClass = $rootClass;
+        $this->defaultGroups = $defaultGroups;
+        $this->normalization = $normalization;
+        $this->groups = $groups;
+        sort($this->groups);
+    }
+
+    /**
+     * @param bool $normalization
+     *
+     * @return Context
+     */
+    public function withNormalization(bool $normalization): ContextInterface
+    {
+        if ($normalization === $this->normalization) {
+            return $this;
+        }
+
+        $clone = clone $this;
+        $clone->normalization = $normalization;
+
+        return $clone;
+    }
+
+    /**
+     * @param bool $normalization
+     *
+     * @return Context
+     */
+    public function withGroups(array $groups): ContextInterface
+    {
+        sort($groups);
+
+        /* @noinspection TypeUnsafeComparisonInspection */
+        if ($groups == $this->groups) {
+            return $this;
+        }
+
+        $clone = clone $this;
+        $clone->groups = $groups;
+
+        return $clone;
+    }
+
+    /**
+     * Get rootClass.
+     *
+     * @return string
+     */
+    public function getRootClass(): string
+    {
+        return $this->rootClass;
+    }
+
+    /**
+     * @return bool
+     */
+    public function isNormalization(): bool
+    {
+        return $this->normalization;
+    }
+
+    /**
+     * @return array
+     */
+    public function getGroups(): array
+    {
+        return $this->groups;
+    }
+
+    /**
+     * @param string $className
+     *
+     * @return string[]
+     */
+    public function getDefaultGroups(string $className): array
+    {
+        return $this->defaultGroups[$this->normalization ? 'normalization' : 'denormalization'][$className] ?? [];
+    }
+}
diff --git a/src/ContextInterface.php b/src/ContextInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..d03fdf91d82298f67f1c5ac8f7b6c86bd0becf37
--- /dev/null
+++ b/src/ContextInterface.php
@@ -0,0 +1,64 @@
+<?php declare(strict_types=1);
+/*
+ * irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata.
+ * Copyright (C) 2018 IRSTEA
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License and the GNU
+ * Lesser General Public License along with this program. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+namespace Irstea\NgModelGeneratorBundle;
+
+/**
+ * Interface ContextInterface.
+ */
+interface ContextInterface
+{
+    /**
+     * @param bool $normalization
+     *
+     * @return Context
+     */
+    public function withNormalization(bool $normalization): self;
+
+    /**
+     * @param bool $normalization
+     *
+     * @return Context
+     */
+    public function withGroups(array $groups): self;
+
+    /**
+     * Get rootClass.
+     *
+     * @return string
+     */
+    public function getRootClass(): string;
+
+    /**
+     * @return bool
+     */
+    public function isNormalization(): bool;
+
+    /**
+     * @return array
+     */
+    public function getGroups(): array;
+
+    /**
+     * @param string $className
+     *
+     * @return string[]
+     */
+    public function getDefaultGroups(string $className): array;
+}
diff --git a/src/DefaultNamingStrategy.php b/src/DefaultNamingStrategy.php
new file mode 100644
index 0000000000000000000000000000000000000000..5f7ec0e802d7e27e49ed34e274ec9eea241bacec
--- /dev/null
+++ b/src/DefaultNamingStrategy.php
@@ -0,0 +1,62 @@
+<?php declare(strict_types=1);
+/*
+ * irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata.
+ * Copyright (C) 2018 IRSTEA
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License and the GNU
+ * Lesser General Public License along with this program. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+namespace Irstea\NgModelGeneratorBundle;
+
+/**
+ * Class DefaultNamingStrategy.
+ */
+final class DefaultNamingStrategy implements NamingStrategy
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function getName(ContextInterface $ctx, string $resourceClass): string
+    {
+        $parts = array_diff(
+            $ctx->getGroups(),
+            $ctx->getDefaultGroups($resourceClass),
+            $ctx->getDefaultGroups($ctx->getRootClass())
+        );
+
+        $baseName = FQCN::baseName($resourceClass);
+        $shortPrefix = $ctx->isNormalization() ? '' : 'Put';
+        $fullPrefix = $ctx->isNormalization() ? 'Get' : 'Put';
+
+        if ($resourceClass === $ctx->getRootClass()) {
+            if (\in_array($shortPrefix . $baseName, $parts, true)) {
+                array_unshift($parts, $baseName);
+            } else {
+                array_unshift($parts, $shortPrefix . $baseName);
+            }
+        } else {
+            $rootBaseName = FQCN::baseName($ctx->getRootClass());
+            $rootGroup = $fullPrefix . $rootBaseName;
+            if (\in_array($rootGroup, $parts, true)) {
+                array_unshift($parts, $rootBaseName);
+            } else {
+                array_unshift($parts, $rootGroup);
+            }
+
+            $parts[] = $baseName;
+        }
+
+        return implode('', $parts);
+    }
+}
diff --git a/src/ModelGenerator.php b/src/ModelGenerator.php
index 81b94ebdaa9a9d90f670573340591972ee54dd41..294272d427d27e87d0cbba1ce40bbdc5c326cb60 100644
--- a/src/ModelGenerator.php
+++ b/src/ModelGenerator.php
@@ -34,14 +34,13 @@ use Irstea\NgModelGeneratorBundle\Models\Types\Reference;
 use Irstea\NgModelGeneratorBundle\Models\Types\Repository;
 use Irstea\NgModelGeneratorBundle\Models\Types\Representation;
 use Irstea\NgModelGeneratorBundle\Models\Types\Type;
-use Irstea\NgModelGeneratorBundle\Models\Types\TypeFactoryInterface;
 use Symfony\Component\PropertyInfo\Type as PHPType;
 use Twig\Environment;
 
 /**
  * Class Serializer.
  */
-final class ModelGenerator implements ResourceTypeFactoryFactory
+final class ModelGenerator
 {
     /** @var MetadataFactoryInterface */
     private $metadataFactory;
@@ -137,9 +136,9 @@ final class ModelGenerator implements ResourceTypeFactoryFactory
     /**
      * Crée une usine à types contenant un certain nombre de types par défaut.
      *
-     * @return TypeFactory
+     * @return TypeFactoryInterface
      */
-    private function createTypeFactory(): TypeFactory
+    private function createTypeFactory(): TypeFactoryInterface
     {
         $factory = new TypeFactory();
 
@@ -181,7 +180,11 @@ final class ModelGenerator implements ResourceTypeFactoryFactory
             $factory->addAlias($alias, $target);
         }
 
-        return $factory;
+        return new ResourceTypeFactory(
+            $this->metadataFactory,
+            $factory,
+            new DefaultNamingStrategy()
+        );
     }
 
     /**
@@ -238,39 +241,27 @@ final class ModelGenerator implements ResourceTypeFactoryFactory
 
         /** @var string $className */
         foreach ($this->getResourceMetadata() as $className => $resourceMeta) {
-            $resources[$className] = [];
+            $representations[$className] = [];
 
             foreach (['normalization', 'denormalization'] as $normalization) {
-                $representations[$className][$normalization] = $this
-                    ->createResourceTypeFactory(
-                        $this->defaultGroups[$normalization][$className],
-                        $normalization === 'normalization'
-                    )
-                    ->get($className)
-                    ->dereference();
+                $ctx = new Context(
+                    $className,
+                    $this->defaultGroups,
+                    $normalization === 'normalization',
+                    $this->defaultGroups[$normalization][$className]
+                );
+
+                $representations[$className][$normalization] =
+                    $this->typeFactory
+                        ->withContext($ctx)
+                        ->get($className)
+                        ->dereference();
             }
         }
 
         return $representations;
     }
 
-    /**
-     * @param $groups
-     * @param $normalization
-     *
-     * @return TypeFactoryInterface
-     */
-    public function createResourceTypeFactory(array $groups, bool $normalization): TypeFactoryInterface
-    {
-        return new ResourceTypeFactory(
-            $this->metadataFactory,
-            $this->typeFactory,
-            $groups,
-            $normalization,
-            $this->defaultGroups[$normalization ? 'normalization' : 'denormalization'] ?? []
-        );
-    }
-
     /**
      * @return array
      */
@@ -282,18 +273,20 @@ final class ModelGenerator implements ResourceTypeFactoryFactory
         foreach ($this->getResourceMetadata() as $className => $resourceMeta) {
             $repoName = $resourceMeta->getShortName() . 'Repository';
 
+            $ctx = new Context($className, $this->defaultGroups);
+
             $repositories[$repoName] = $this->typeFactory->getOrCreate(
                 $repoName,
 
-                function () use ($resourceMeta, $className, &$iriPatterns): Type {
+                function () use ($resourceMeta, $className, &$iriPatterns, $ctx): Type {
                     $operations = [];
 
                     foreach ($resourceMeta->getOperations() as $operation) {
                         $mapper = new OperationMapper(
-                            $this,
-                            $this->typeFactory,
+                            $this->typeFactory->withContext($ctx),
                             $operation,
-                            $this->resources[$className]['normalization']
+                            $this->resources[$className]['normalization'],
+                            $ctx
                         );
                         $operations[] = $operation = $mapper();
 
diff --git a/src/ResourceTypeFactoryFactory.php b/src/NamingStrategy.php
similarity index 73%
rename from src/ResourceTypeFactoryFactory.php
rename to src/NamingStrategy.php
index cae52adc9fbc66cfa4c74a7970f66cddd6f8b718..e5184a7d84ca02763f491446ce0db682af3db9a2 100644
--- a/src/ResourceTypeFactoryFactory.php
+++ b/src/NamingStrategy.php
@@ -19,18 +19,16 @@
 
 namespace Irstea\NgModelGeneratorBundle;
 
-use Irstea\NgModelGeneratorBundle\Models\Types\TypeFactoryInterface;
-
 /**
- * Class ResourceTypeFactoryFactory.
+ * Interface NamingStrategy.
  */
-interface ResourceTypeFactoryFactory
+interface NamingStrategy
 {
     /**
-     * @param array $groups
-     * @param bool  $normalization
+     * @param ContextInterface $context
+     * @param string           $resourceClass
      *
-     * @return TypeFactoryInterface
+     * @return mixed
      */
-    public function createResourceTypeFactory(array $groups, bool $normalization): TypeFactoryInterface;
+    public function getName(ContextInterface $context, string $resourceClass);
 }
diff --git a/src/OperationMapper.php b/src/OperationMapper.php
index 15a246d2f429fc64acac2d4be1e50ec863f2cb39..a2483f57b2a0d78995cc1ae48cfb82560ef4ad78 100644
--- a/src/OperationMapper.php
+++ b/src/OperationMapper.php
@@ -34,7 +34,6 @@ use Irstea\NgModelGeneratorBundle\Models\Types\ObjectClass;
 use Irstea\NgModelGeneratorBundle\Models\Types\Property;
 use Irstea\NgModelGeneratorBundle\Models\Types\Representation;
 use Irstea\NgModelGeneratorBundle\Models\Types\Type;
-use Irstea\NgModelGeneratorBundle\Models\Types\TypeFactoryInterface;
 use Irstea\NgModelGeneratorBundle\Models\Types\Union;
 use Symfony\Component\PropertyInfo\Type as APIType;
 
@@ -58,9 +57,6 @@ final class OperationMapper
         'post'   => 'post(%s)',
     ];
 
-    /** @var ResourceTypeFactoryFactory */
-    private $resourceTypeFactoryFactory;
-
     /** @var TypeFactoryInterface */
     private $typeFactory;
 
@@ -70,20 +66,23 @@ final class OperationMapper
     /** @var Representation */
     private $baseRepr;
 
+    /** @var ContextInterface */
+    private $context;
+
     /**
      * OperationMapper constructor.
      *
-     * @param ResourceTypeFactoryFactory $resourceTypeFactoryFactory
-     * @param TypeFactoryInterface       $typeFactory
-     * @param OperationMetadata          $operation
-     * @param Representation             $baseRepr
+     * @param TypeFactoryInterface $typeFactory
+     * @param OperationMetadata    $operation
+     * @param Representation       $baseRepr
+     * @param ContextInterface     $context
      */
-    public function __construct(ResourceTypeFactoryFactory $resourceTypeFactoryFactory, TypeFactoryInterface $typeFactory, OperationMetadata $operation, Representation $baseRepr)
+    public function __construct(TypeFactoryInterface $typeFactory, OperationMetadata $operation, Representation $baseRepr, ContextInterface $context)
     {
-        $this->resourceTypeFactoryFactory = $resourceTypeFactoryFactory;
         $this->typeFactory = $typeFactory;
         $this->operation = $operation;
         $this->baseRepr = $baseRepr;
+        $this->context = $context;
     }
 
     /**
@@ -102,20 +101,22 @@ final class OperationMapper
         $requestBody = $responseBody = $queryParameters = null;
 
         if ($denormalize) {
-            $requestBody = $this->resourceTypeFactoryFactory
-                ->createResourceTypeFactory(
-                    $this->operation->getAttribute('denormalization_groups'),
-                    false
+            $requestBody = $this->typeFactory
+                ->withContext(
+                    $this->context
+                        ->withNormalization(false)
+                        ->withGroups($this->operation->getAttribute('denormalization_groups'))
                 )
                 ->get($className)
                 ->dereference();
         }
 
         if ($normalize) {
-            $responseBody = $this->resourceTypeFactoryFactory
-                ->createResourceTypeFactory(
-                    $this->operation->getAttribute('normalization_groups'),
-                    true
+            $responseBody = $this->typeFactory
+                ->withContext(
+                    $this->context
+                        ->withNormalization(true)
+                        ->withGroups($this->operation->getAttribute('normalization_groups'))
                 )
                 ->get($className)
                 ->dereference();
diff --git a/src/ResourceTypeFactory.php b/src/ResourceTypeFactory.php
index 4123b22e7bd1da6cd1b09fffd18433d991411649..b4c0064bc0907b3a72270dcae3adcdeb4f71aac4 100644
--- a/src/ResourceTypeFactory.php
+++ b/src/ResourceTypeFactory.php
@@ -24,13 +24,10 @@ use Irstea\NgModelGeneratorBundle\Models\Metadata\PropertyMetadata;
 use Irstea\NgModelGeneratorBundle\Models\Types\BuiltinType;
 use Irstea\NgModelGeneratorBundle\Models\Types\Collection;
 use Irstea\NgModelGeneratorBundle\Models\Types\GenericRef;
-use Irstea\NgModelGeneratorBundle\Models\Types\Placeholder;
 use Irstea\NgModelGeneratorBundle\Models\Types\Property;
 use Irstea\NgModelGeneratorBundle\Models\Types\Representation;
 use Irstea\NgModelGeneratorBundle\Models\Types\StringConst;
 use Irstea\NgModelGeneratorBundle\Models\Types\Type;
-use Irstea\NgModelGeneratorBundle\Models\Types\TypeFactoryInterface;
-use Irstea\NgModelGeneratorBundle\Models\Types\Union;
 
 /**
  * Class TypeMapper.
@@ -43,38 +40,48 @@ final class ResourceTypeFactory implements TypeFactoryInterface
     /** @var TypeFactoryInterface */
     private $typeFactory;
 
-    /** @var string[] */
-    private $groups;
+    /** @var NamingStrategy */
+    private $namingStrategy;
 
-    /** @var bool */
-    private $normalization;
-
-    /** @var string[][] */
-    private $defaultGroups;
+    /** @var ContextInterface|null */
+    private $context;
 
     /**
      * TypeMapper constructor.
      *
      * @param MetadataFactoryInterface $metadataFactory
      * @param TypeFactoryInterface     $typeFactory
-     * @param string[]                 $groups
-     * @param bool                     $normalization
-     * @param array                    $defaultGroups
+     * @param NamingStrategy           $namingStrategy
+     * @param ContextInterface         $context
      */
     public function __construct(
         MetadataFactoryInterface $metadataFactory,
         TypeFactoryInterface $typeFactory,
-        array $groups,
-        bool $normalization,
-        array $defaultGroups
+        NamingStrategy $namingStrategy,
+        ContextInterface $context = null
     ) {
         $this->metadataFactory = $metadataFactory;
         $this->typeFactory = $typeFactory;
-        $this->groups = $groups;
-        $this->normalization = $normalization;
-        $this->defaultGroups = $defaultGroups;
+        $this->namingStrategy = $namingStrategy;
+        $this->context = $context;
+    }
 
-        sort($this->groups);
+    /**
+     * @param ContextInterface|null $context
+     *
+     * @return TypeFactoryInterface
+     */
+    public function withContext(?ContextInterface $context): TypeFactoryInterface
+    {
+        if ($context === $this->context) {
+            return $this;
+        }
+
+        $clone = clone $this;
+        $clone->context = $context;
+        $clone->typeFactory = $clone->typeFactory->withContext($context);
+
+        return $clone;
     }
 
     /**
@@ -98,12 +105,12 @@ final class ResourceTypeFactory implements TypeFactoryInterface
      */
     public function get(string $name): Type
     {
-        if (!class_exists($name) || $this->typeFactory->has($name)) {
+        if (!$this->context || !class_exists($name) || $this->typeFactory->has($name)) {
             return $this->typeFactory->get($name);
         }
 
         if ($this->metadataFactory->isResource($name)) {
-            $reprName = $this->getRepresentationName($name);
+            $reprName = $this->namingStrategy->getName($this->context, $name);
 
             return $this->typeFactory->getOrCreate(
                 $reprName,
@@ -140,26 +147,6 @@ final class ResourceTypeFactory implements TypeFactoryInterface
         return $this->typeFactory->getGenericRef($defName, $parameters);
     }
 
-    /**
-     * @param string $resourceFQCN
-     *
-     * @return string
-     */
-    private function getRepresentationName(string $resourceFQCN): string
-    {
-        $name = FQCN::baseName($resourceFQCN);
-
-        if ($this->groups != $this->defaultGroups[$resourceFQCN]) {
-            $name .= implode('', $this->groups);
-        }
-
-        if (!$this->normalization && strpos($name, 'Put') === false) {
-            $name = 'Put' . $name;
-        }
-
-        return $name;
-    }
-
     /**
      * @param string $name
      * @param string $resourceClass
@@ -170,22 +157,30 @@ final class ResourceTypeFactory implements TypeFactoryInterface
     {
         $resourceMeta = $this->metadataFactory->getResourceMetadata($resourceClass);
 
-        $propertiesMeta = $resourceMeta->getProperties($this->groups);
+        $normalization = $this->context->isNormalization();
+        $groups = $this->context->getGroups();
+
+        $propertiesMeta = $resourceMeta->getProperties($groups);
         $properties = $this->mapProperties($propertiesMeta);
 
         $parents = [];
 
-        if ($this->normalization) {
+        if ($normalization) {
             $shortName = $resourceMeta->getShortName();
 
-            $properties['@id'] = Property::createIdentifier('@id', 'JSON-LD identifier', $this->typeFactory->getGenericRef('IRI<T>', [BuiltinType::get($shortName)]));
+            $properties['@id'] = Property::createIdentifier(
+                '@id',
+                'JSON-LD identifier',
+                $this->typeFactory->getGenericRef('IRI<T>', [BuiltinType::get($shortName)])
+            );
 
             $properties['@type'] = Property::createIdentifier('@type', 'JSON-LD type', StringConst::get($shortName));
         }
 
         $desc = [$resourceMeta->getDescription()];
-        $desc[] = 'Direction: ' . ($this->normalization ? 'response' : 'request');
-        $desc[] = sprintf('Serialization groups: %s', $this->groups ? implode(', ', $this->groups) : '-');
+        $desc[] = 'Resource: ' . $resourceClass;
+        $desc[] = 'Direction: ' . ($normalization ? 'response' : 'request');
+        $desc[] = sprintf('Serialization groups: %s', $groups ? implode(', ', $groups) : '-');
 
         return new Representation($resourceClass, $name, $parents, $properties, trim(implode("\n", $desc)));
     }
@@ -236,7 +231,7 @@ final class ResourceTypeFactory implements TypeFactoryInterface
      */
     private function acceptProperty(PropertyMetadata $propertyMeta): bool
     {
-        return $this->normalization ? $propertyMeta->isReadable() : $propertyMeta->isWritable();
+        return $this->context->isNormalization() ? $propertyMeta->isReadable() : $propertyMeta->isWritable();
     }
 
     /**
diff --git a/src/TypeFactory.php b/src/TypeFactory.php
index 12afde8a7d4560aa820faa56b4ecabab1a302943..7b8036091934649c5066fb2777e0d1e73e1f1a80 100644
--- a/src/TypeFactory.php
+++ b/src/TypeFactory.php
@@ -26,17 +26,23 @@ use Irstea\NgModelGeneratorBundle\Models\Types\GenericDef;
 use Irstea\NgModelGeneratorBundle\Models\Types\GenericRef;
 use Irstea\NgModelGeneratorBundle\Models\Types\Reference;
 use Irstea\NgModelGeneratorBundle\Models\Types\Type;
-use Irstea\NgModelGeneratorBundle\Models\Types\TypeFactoryInterface;
 
 /**
  * Class TypeFactory.
  */
 final class TypeFactory implements TypeFactoryInterface, \IteratorAggregate
 {
+    /** @var Type[] */
+    private $types = [];
+
     /**
-     * @var array<string,Type>
+     * {@inheritdoc}
      */
-    private $types = [];
+    public function withContext(?ContextInterface $context): TypeFactoryInterface
+    {
+        // On utilise pas le contexte dans cette classe, donc en changer ne change rien.
+        return $this;
+    }
 
     /**
      * {@inheritdoc}
diff --git a/src/Models/Types/TypeFactoryInterface.php b/src/TypeFactoryInterface.php
similarity index 85%
rename from src/Models/Types/TypeFactoryInterface.php
rename to src/TypeFactoryInterface.php
index 01a122ff92e4ffb35d0a316f07a0d2cf013947a5..ba77323c55e11f1ac91b716ab4854decedf0b1e1 100644
--- a/src/Models/Types/TypeFactoryInterface.php
+++ b/src/TypeFactoryInterface.php
@@ -17,13 +17,23 @@
  * <https://www.gnu.org/licenses/>.
  */
 
-namespace Irstea\NgModelGeneratorBundle\Models\Types;
+namespace Irstea\NgModelGeneratorBundle;
+
+use Irstea\NgModelGeneratorBundle\Models\Types\GenericRef;
+use Irstea\NgModelGeneratorBundle\Models\Types\Type;
 
 /**
  * Interface TypeFactoryInterface.
  */
 interface TypeFactoryInterface
 {
+    /**
+     * @param ContextInterface|null $context
+     *
+     * @return TypeFactoryInterface
+     */
+    public function withContext(?ContextInterface $context): self;
+
     /**
      * @param string $name
      *
diff --git a/tests/DefaultNamingStrategyTest.php b/tests/DefaultNamingStrategyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d71c35ecc9e25df07451b36ff29f0470088094c7
--- /dev/null
+++ b/tests/DefaultNamingStrategyTest.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types=1);
+/*
+ * irstea/ng-model-generator-bundle generates Typescript interfaces for Angular using api-platform metadata.
+ * Copyright (C) 2018 IRSTEA
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License and the GNU
+ * Lesser General Public License along with this program. If not, see
+ * <https://www.gnu.org/licenses/>.
+ */
+
+namespace Irstea\NgModelGeneratorBundle\Tests;
+
+use Irstea\NgModelGeneratorBundle\ContextInterface;
+use Irstea\NgModelGeneratorBundle\DefaultNamingStrategy;
+use PHPUnit\Framework\TestCase;
+use Prophecy\Argument;
+use Prophecy\Prophecy\ObjectProphecy;
+
+/**
+ * Class DefaultNamingStrategyTest.
+ */
+class DefaultNamingStrategyTest extends TestCase
+{
+    /**
+     * @dataProvider getNameTestCaseProvider
+     */
+    public function testGetName(string $expected, string $resourceClass, string $rootClass, bool $normalization, array $groups, array $defaultGroups)
+    {
+        /** @var ObjectProphecy|ContextInterface $ctx */
+        $ctx = $this->prophesize(ContextInterface::class);
+        $ctx->getRootClass()->willReturn($rootClass);
+        $ctx->isNormalization()->willReturn($normalization);
+        $ctx->getGroups()->willReturn($groups);
+        $ctx->getDefaultGroups(Argument::type('string'))->will(function ($args) use ($defaultGroups) {
+            return $defaultGroups[$args[0]] ?? [];
+        });
+
+        $strategy = new DefaultNamingStrategy();
+
+        $actual = $strategy->getName($ctx->reveal(), $resourceClass);
+
+        self::assertEquals($expected, $actual);
+    }
+
+    /**
+     * @return array
+     */
+    public function getNameTestCaseProvider(): array
+    {
+        return [
+            // expected      resource      root          norm?  groups?     defaultGroups ?
+            ['Bar',             '\\App\\Bar', '\\App\\Bar', true,  [],         []],
+            ['BarGetBar',       '\\App\\Bar', '\\App\\Bar', true,  ['GetBar'], []],
+            ['Bar',             '\\App\\Bar', '\\App\\Bar', true,  ['GetBar'], ['\\App\\Bar' => ['GetBar']]],
+            ['BarGetQuz',       '\\App\\Bar', '\\App\\Bar', true,  ['GetQuz'], []],
+
+            ['PutBar',          '\\App\\Bar', '\\App\\Bar', false, [],         []],
+            ['BarPutBar',       '\\App\\Bar', '\\App\\Bar', false, ['PutBar'], []],
+            ['PutBar',          '\\App\\Bar', '\\App\\Bar', false, ['PutBar'], ['\\App\\Bar' => ['PutBar']]],
+            ['PutBarPutQuz',    '\\App\\Bar', '\\App\\Bar', false, ['PutQuz'], []],
+
+            ['GetBarFoo',       '\\App\\Foo', '\\App\\Bar', true,  [],         []],
+            ['BarGetBarFoo',    '\\App\\Foo', '\\App\\Bar', true,  ['GetBar'], []],
+            ['GetBarFoo',       '\\App\\Foo', '\\App\\Bar', true,  ['GetBar'], ['\\App\\Bar' => ['GetBar']]],
+            ['GetBarGetFooFoo', '\\App\\Foo', '\\App\\Bar', true,  ['GetFoo'], []],
+            ['GetBarGetFooFoo', '\\App\\Foo', '\\App\\Bar', true,  ['GetFoo', 'GetBar'], ['\\App\\Bar' => ['GetBar']]],
+            ['GetBarFoo',       '\\App\\Foo', '\\App\\Bar', true,  ['GetFoo'], ['\\App\\Foo' => ['GetFoo']]],
+            ['GetBarGetQuzFoo', '\\App\\Foo', '\\App\\Bar', true,  ['GetQuz'], []],
+
+            ['PutBarFoo',       '\\App\\Foo', '\\App\\Bar', false, [],         []],
+            ['BarPutBarFoo',    '\\App\\Foo', '\\App\\Bar', false, ['PutBar'], []],
+            ['PutBarFoo',       '\\App\\Foo', '\\App\\Bar', false, ['PutBar'], ['\\App\\Bar' => ['PutBar']]],
+            ['PutBarPutFooFoo', '\\App\\Foo', '\\App\\Bar', false, ['PutFoo'], []],
+            ['PutBarPutFooFoo', '\\App\\Foo', '\\App\\Bar', false, ['PutFoo', 'PutBar'], ['\\App\\Bar' => ['PutBar']]],
+            ['PutBarFoo',       '\\App\\Foo', '\\App\\Bar', false, ['PutFoo'], ['\\App\\Foo' => ['PutFoo']]],
+            ['PutBarPutQuzFoo', '\\App\\Foo', '\\App\\Bar', false, ['PutQuz'], []],
+        ];
+    }
+}