solidprinciples Archives - ProdSens.live https://prodsens.live/tag/solidprinciples/ News for Project Managers - PMI Sat, 25 May 2024 01:20:45 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.5 https://prodsens.live/wp-content/uploads/2022/09/prod.png solidprinciples Archives - ProdSens.live https://prodsens.live/tag/solidprinciples/ 32 32 [S.O.L.I.D.] Os Cinco Pilares da Programação Orientada a Objetos. [L] – Liskov Substitution Principle – LSP https://prodsens.live/2024/05/25/s-o-l-i-d-os-cinco-pilares-da-programacao-orientada-a-objetos-l-liskov-substitution-principle-lsp/?utm_source=rss&utm_medium=rss&utm_campaign=s-o-l-i-d-os-cinco-pilares-da-programacao-orientada-a-objetos-l-liskov-substitution-principle-lsp https://prodsens.live/2024/05/25/s-o-l-i-d-os-cinco-pilares-da-programacao-orientada-a-objetos-l-liskov-substitution-principle-lsp/#respond Sat, 25 May 2024 01:20:45 +0000 https://prodsens.live/2024/05/25/s-o-l-i-d-os-cinco-pilares-da-programacao-orientada-a-objetos-l-liskov-substitution-principle-lsp/ [solid]-os-cinco-pilares-da-programacao-orientada-a-objetos.-[l]-–-liskov-substitution-principle-–-lsp

Continuando a série sobre SOLID, caso não tenha lido o artigo anterior: [S.O.L.I.D.] Os Cinco Pilares da Programação…

The post [S.O.L.I.D.] Os Cinco Pilares da Programação Orientada a Objetos. [L] – Liskov Substitution Principle – LSP appeared first on ProdSens.live.

]]>
[solid]-os-cinco-pilares-da-programacao-orientada-a-objetos.-[l]-–-liskov-substitution-principle-–-lsp

Continuando a série sobre SOLID, caso não tenha lido o artigo anterior:

Neste artigo estarei falando sobre o terceiro princípio que é:
[L] -Liskov Substitution Principle
Princípio da Substituição de Liskov – LSP
“Se para cada objeto o1 do tipo S há um objeto o2 do tipo T de forma que, para todos os programas P definidos em termos de T, o comportamento de P é inalterado quando o1 é substituído por o2 então S é um subtipo de T.”

O Princípio de Substituição de Liskov leva esse nome por ter sido criado por Barbara Liskov, em 1988.

Tal definição foi resumida e popularizada por Robert C. Martin (Uncle Bob), em seu livro “Agile Principles Patterns and Practices”, como:

“Classes derivadas devem poder ser substitutas de suas classes base”

Ou seja, toda classe derivada deve poder ser usada como se fosse a classe base.

Para mim, foi um dos conceitos mais difíceis de entender. Portanto, não se preocupe se não conseguir compreender de imediato. Tenho esperança de que, com os exemplos de código, você sairá deste artigo entendendo esse princípio.

Vamos criar um sistema de notificações onde inicialmente temos um EmailNotification e, posteriormente, adicionamos um SMSNotification.

Veremos como implementar isso sem e com o LSP.

Sem LSP
Classe Notification e EmailNotification sem LSP
Image description

Adicionando SMSNotification sem LSP
Image description

Neste exemplo, a classe SMSNotification altera o comportamento esperado ao adicionar uma verificação de número de telefone, o que pode causar problemas quando substituímos a classe base Notification pela classe derivada SMSNotification.

Image description

Com LSP
Para seguir o LSP, devemos projetar nossas classes de forma que respeitem as expectativas da superclasse e evitem adicionar comportamentos que possam quebrar a substituição.

Interface Notification
Image description

Classe EmailNotification
Image description

Classe SMSNotification
Image description

Uso das Classes
Image description

Explicação:

  • Interface Notification: Define o contrato para uma notificação. Todas as notificações devem implementar os métodos setRecipient, setMessage e send.
  • Classe EmailNotification: Implementa a interface Notification e define a lógica específica para enviar um email.
  • Classe SMSNotification: Implementa a interface Notification e define a lógica específica para enviar um SMS. A verificação do número de telefone é feita no método setRecipient, garantindo que qualquer configuração inválida seja tratada antes de tentar enviar a notificação.
  • Uso das Classes: Demonstramos como criar e usar instâncias de EmailNotification e SMSNotification de forma intercambiável através da interface Notification, respeitando o LSP.

Ao seguir o Princípio da Substituição de Liskov, garantimos que nossas subclasses podem ser usadas em qualquer contexto onde a superclasse é esperada, sem alterar o comportamento correto do programa. Isso torna o código mais robusto e facilita a manutenção e extensão do sistema.

The post [S.O.L.I.D.] Os Cinco Pilares da Programação Orientada a Objetos. [L] – Liskov Substitution Principle – LSP appeared first on ProdSens.live.

]]>
https://prodsens.live/2024/05/25/s-o-l-i-d-os-cinco-pilares-da-programacao-orientada-a-objetos-l-liskov-substitution-principle-lsp/feed/ 0
Reflexões sobre SOLID – Princípios Básicos https://prodsens.live/2024/05/02/reflexoes-sobre-solid-principios-basicos/?utm_source=rss&utm_medium=rss&utm_campaign=reflexoes-sobre-solid-principios-basicos https://prodsens.live/2024/05/02/reflexoes-sobre-solid-principios-basicos/#respond Thu, 02 May 2024 18:20:34 +0000 https://prodsens.live/2024/05/02/reflexoes-sobre-solid-principios-basicos/ reflexoes-sobre-solid-–-principios-basicos

Recentemente, tenho refletido bastante sobre alguns padrões de desenvolvimento, boas práticas e qualidade de código. Diversas ideias vêm…

The post Reflexões sobre SOLID – Princípios Básicos appeared first on ProdSens.live.

]]>
reflexoes-sobre-solid-–-principios-basicos

Recentemente, tenho refletido bastante sobre alguns padrões de desenvolvimento, boas práticas e qualidade de código. Diversas ideias vêm à mente com um tema tão abrangente, mas nesta série de artigos, gostaria de explorar especificamente o padrão de design que hoje conhecemos como “SOLID”, acrescentando algumas visões pessoais sobre sua filosofia, suas implementações concretas, e sobre cada letra que o compõe.

Neste artigo

Sobre suas origens
Sobre sua importância
Sobre sua definição
Sobre sua aplicabilidade
Reflexões finais
Textos complementares

Sobre suas origens

Sobre suas origens

Inicialmente propostos por Robert C. Martin em seu artigo “Design Principles and Design Patterns” de 2000, e posteriormente expandido por Michael Feathers para enclausurá-los no acrônimo que conhecemos hoje, os princípios SOLID foram cimentados no âmbito da Engenharia de Software como padrões essenciais para construção de software robusto, de fácil manutenção e escalável.

Esse é o resumo como conhecemos hoje, mais de 20 anos depois de sua concepção. É interessante vermos como, atualmente, essa visão atinge exatamente aquilo que toda pessoa engenheira de software, assim como qualquer corporação com ativos tecnológicos, busca como resultado: robustez, mantenabilidade, escalabilidade e qualidade.

Talvez por conta disso, SOLID acabou tornando-se uma “buzzword” nos últimos anos – ou seja, uma nomenclatura de fácil memorização, onde tanto aqueles que a posicionam como parte de seu conhecimento, quanto os que exigem essa competência para vagas de desenvolvimento, não necessariamente entendem ou pregam sua real aplicabilidade.

Isso não significa que sua base seja descartável, muito pelo contrário. Na verdade, o que acontece é que, vivendo na era de ouro do conteúdo, muitos focam em saber o que é, através de breves explosões de informação, mas nem todos se aprofundam no detalhe essencial de como funciona.

Sobre sua importância

Sobre sua importância

Quando falamos sobre SOLID (ou qualquer outro padrão arquitetural), é importante entendermos que são propostas para melhorarmos nosso trabalho na construção de software. Ou seja, não é algo que você instala em seu produto, uma dependência que você precisa acrescentar na aplicação, e muito menos algo que automaticamente criará um software competente e resolverá todos os problemas existentes e futuros. Os melhores ingredientes e panelas, quando entregues a alguém que não sabe cozinhar, não garante um alimento de qualidade.

Gostaria de destacar uma frase que, para mim, resume muito bem o porquê a adoção de tais propostas e padrões são uma constante em nossa área. Por mais que Martin esteja se direcionando a um tema mais específico em seu artigo no trecho abaixo (design patterns), creio que se aplica aos design principles de forma similar:

A definição essencial de um padrão de design é uma boa solução, bem estabelecida e conhecida, para um problema comum.

Robert C. Martin

Ou seja, tais paradigmas de desenvolvimento têm suas raízes em otimizar o processso de repetição. Ao longo de nossas carreiras, nos encontramos diversas vezes perante problemas em que o compartilhamento de código e ideias acaba apresentando-se naturalmente nas implementações. Duplicamos abordagens, consultamos construções anteriores para nos basearmos para as novas, e assim acabamos por evoluir o código de forma pouco consistente.

Graças aos exercícios de otimização realizados por grandes pensadores e pela comunidade dessa área ao longo dos anos, assim como ocorre com experimentações científicas, bases sólidas começam a surgir, servindo como pontos de partida para a solução de novos problemas. Blocos de códigos que antes eram duplicados agora são transformados em padrões que evitam tais duplicidades, propondo em seu lugar formas de distribuir lógicas de forma reaproveitável.

Sobre sua definição

Sobre sua definição

É nesse ponto que os princípios SOLID se encaixam: como ferramentas multifacetadas para resolver problemas e criar padrões que, conceitualmente, podem ser compartilhados entre membros da equipe, atuais ou futuros (considerando que todos busquem ratear esse conhecimento).

O acrônimo em si identifica os 5 princípios, não necessariamente em ordem de importância, mas na ordem para formar a palavra solid (sólido, em português), criando todo o vínculo criativo com o conceito de robustez:

  • Single Responsibility Principle: Princípio da Responsabilidade Única – Classes devem ter somente uma responsabilidade, e portanto, um único motivo para mudar;
  • Open/Closed Principle: Princípio do Aberto/Fechado – Classes devem ser fechadas para modificação, mas abertas para estensões;
  • Liskov Substitution Principle – Princípio de Substituição de Liskov – Classes devem ser facilmente substituíveis por suas subclasses;
  • Interface Segretation Principle – Princípio da Segregação de Interface – É melhor ter múltiplas interfaces específicas do que uma única interface genérica.;
  • Dependency Inversion Principle – Princípio da Inversão de Dependência – Classes devem depender de interfaces e abstrações, e não de implementações concretas.

Lendo somente o descritivo de cada letra, fica claro o porquê de tantas pessoas sentirem pouca confiança, ou muita confusão, nesse tópico. Digo isso por experiência: sem exemplos concretos ou demonstrações práticas, fica difícil compreender o que é “depender de abstrações e não de implementações”, ou até mesmo por qual motivo você precisaria “substituir uma subclasse” sem entender o devido contexto. O artigo original de Martin inclui constantemente exemplos, por mais abstratos que sejam, visto que é realmente um tema que pode passar despercebido se não conseguirmos visualizá-lo.

Um ponto interessante é que todos os conceitos abordam o tema de classes, exceto a letra I, que é o único que abrange a visão de interfaces. Ou seja, o nascimento do SOLID (e dos design patterns intrinsicamente ligados à sua filosofia), estão amarrados ao paradigma de OOP (Object-Oriented Programming, ou Programação Orientada a Objeto). É importante considerar o momento em que o artigo de Martin foi publicado, o que nos leva a pensar sobre a maturidade deste padrão e de sua longevidade naquele momento da história.

Isso não significa que os princípios SOLID sejam limitados somente a essa forma de implementação, pelo menos a nível de código. Outros modelos de desenvolvimento, como FP (Functional Programming – Programação Funcional), também podem beber da mesma fonte na questão de ideologia. O que quero dizer é que as ideias propostas, de termos criticidade na visão analítica sobre interfaces e entidades, podem fazer sentido também em outros contextos no qual lidaremos com essas iterações. Pretendo me aprofundar nessa ideia em partes futuras dessa série.

Sobre sua aplicabilidade

Ao entender as definições, podemos nos perguntar (eu, pelo menos, me perguntei na primeira vez): “Certo, isso tudo é muito interessante, mas e na prática? Como aplico esses conceitos no meu dia-a-dia? Como encontro oportunidades nos meus projetos para exercitar esses conhecimentos?”. Em meio a isso, existe um perigoso impulso que pode surgir, e é mais do que imprescindível reforçamos uma breve realidade: talvez você não precisará usar todas as letras, ao mesmo tempo, nem o tempo inteiro.

Os princípios SOLID, assim como qualquer padrão de design ou arquitetural, são um pouco mais empíricos do que outras áreas de conhecimento, exigindo que antes exercitemos nossa visão analítica do que somente o conhecimento técnico. Muitos problemas já conhecidos podem ser resolvidos de uma forma elegante, garantida e bem estabelecida – mas será que o problema que você possui se encaixa nessa solução? Ou você está buscando problemas para exercitar um ensaio de engenharia de software?

Com base nas minhas turbulentas primeiras experiências com esses paradigmas, consegui abstrair 3 pontos de partida que podem auxiliar no entendimento e facilitar a real aplicação da visão conceitual:

  1. Entender a essência abstraída: Antes de observar um código ou um exemplo prático, tente entender o que cada letra significa e o que ela propõe a nível de design, não de código. Ou seja, independentemente da linguagem ou framework em uso, quais os ganhos a nível da estrutura da aplicação? E as perdas? O próprio artigo de Martin é um excelente ponto de partida, mas como mencionei anteriormente, conteúdos online com linguagens mais informais (ou formais, conforme sua preferência) é o que menos falta em nossa era.

  2. Exercitar exemplos da sua realidade: De nada adiantará se os exemplos que você buscar fugirem muito dos seus conhecimentos concretos. Por mais reais que eles possam ser, é possível que eles não sejam condizentes com a sua realidade pessoal. Pessoalmente, tive bastante contato com FinTechs e projetos para chão de fábrica, e pensar em entidades relacionadas nesses contextos me ajuda bastante. E claro, pense em sistemas – o funcionamento de uma biblioteca municipal é algo bastante universal, por exemplo. Você pode até mesmo se basear em hobbies pessoais, visualizar algo que você gosta e domina e enxergá-lo com esse olhar analítico (quando penso em videogames, não consigo contar quantas vezes utilizei Super Mario 64, Banjo-Kazooie e Donkey Kong 64 como chaves de leitura).

  3. Buscar uma visão analítica: Comece a observar, no seu dia-a-dia, as entidades com as quais você trabalha, por mais simples que seu projeto seja. Será que ele já está otimizado o suficiente? Você consegue enxergar duplicidade de código ou de implementações? Existe algo que poderia ser mais genérico, ou talvez mais específico? Tome alguns minutos do seu dia para fazer essa reflexão e realmente busque entender o sistema por trás do produto – faça anotações, diagramas, um breve descritivo, e busque os relacionamentos. Não é fácil, e não é uma competência que surgirá da noite para o dia, mas o ideal é começar por algum lugar. Recomendo alternar também entre realizar essa atividade de forma singular e com uma pessoa parceira – analisar em equipe pode trazer insights que talvez passassem despercebidos, visto que cada pessoa terá seu próprio discernimento com base em sua bagagem de experiência.

Reflexões finais

Reflexões finais

Os princípios SOLID compõe um ferramental extremamente poderoso que, se utilizado da forma correta e ponderada, pode trazer diversos benefícios tanto ao software construído quanto àquele que o construiu. Não é a toa que, mesmo décadas depois da ideia original de Robert C. Martin ter sido publicada, continuamos falando sobre, pregando, ensinando e compartilhando ideias sobre o tema. A longevidade de todo o conceito, inclusive o fato de estar sofrendo iterações e evoluções por parte da comunidade, demonstra sua importância determinística.

Existem muitas pessoas que conseguem apresentar o SOLID de forma muito mais elegante, ou mais extravagante, do que eu. Minha ideia com esse artigo foi ruminar um pouco sobre o tema, e apresentar algumas ideias da minha filosofia sobre esse paradigma. 🙂

Obrigado por ter lido até aqui. Em futuras iterações desta série, quero me aprofundar um pouco mais em cada uma das letras, com alguns exemplos práticos e novamente refletindo sobre o tema.

Textos complementares

Design principles and design patterns, artigo de Robert C. Martin, 2000. Consultado em https://staff.cs.utu.fi/~jounsmed/doos_06/material/DesignPrinciplesAndPatterns.pdf

Design Patterns, livro referenciado por Martin como GOF (Gang of Four). Detalhamento sobre o livro pode ser encontrado na Wikipedia. Consultado em https://en.wikipedia.org/wiki/Design_Patterns

The post Reflexões sobre SOLID – Princípios Básicos appeared first on ProdSens.live.

]]>
https://prodsens.live/2024/05/02/reflexoes-sobre-solid-principios-basicos/feed/ 0
Clawject: Simplifying Dependency Injection in TypeScript https://prodsens.live/2024/04/06/clawject-simplifying-dependency-injection-in-typescript/?utm_source=rss&utm_medium=rss&utm_campaign=clawject-simplifying-dependency-injection-in-typescript https://prodsens.live/2024/04/06/clawject-simplifying-dependency-injection-in-typescript/#respond Sat, 06 Apr 2024 14:20:52 +0000 https://prodsens.live/2024/04/06/clawject-simplifying-dependency-injection-in-typescript/ clawject:-simplifying-dependency-injection-in-typescript

Outline Greetings, I’m the creator of Clawject, a dependency injection framework for TypeScript. I’m here to introduce you…

The post Clawject: Simplifying Dependency Injection in TypeScript appeared first on ProdSens.live.

]]>
clawject:-simplifying-dependency-injection-in-typescript

Outline

Greetings, I’m the creator of Clawject, a dependency injection framework for TypeScript. I’m here to introduce you to the world of effortless and type-safe dependency injection.

Have you ever thought that dependency injection in TypeScript could be easier?

Meet Clawject, the first truly type-safe dependency injection framework for TypeScript.

Visit clawject.com for more detailed API end examples.

You diligently write types, interfaces, generics, and all of that to ensure type safety, but it all comes to an end if you mix up an injection token.

@Injectable()
class CatsService {
  constructor(
    @Inject(InjectionTokens.DogsRepository)
    private catsRepository: Repository<Cat>
  ) {}
}

TypeScript will compile this code without any errors, it will execute, and you’ll only find out at runtime that instead of cats, you’re getting dogs. Dogs are also great, but in this case, we specifically need cats.

Now, let’s define CatsService with Clawject.

class CatsService {
  constructor(
    private catsRepository: Repository<Cat>
  ) {}
}

As you can see, Clawject doesn’t require you to attach the @Injectable decorator to the class or specify what exactly you want to inject. Instead, Clawject will take the type of your dependency and find the appropriate implementation at compile time.

If we wanted to avoid attaching the @Injectable decorator to the class without Clawject, you would use something like a Factory providers, but this is quite inconvenient. It requires changes if the class constructor changes and still leaves room for error by mixing up injection tokens. Besides, it’s just not elegant.

const InjectionTokens = {
  DogsRepository: Symbol('dogsRepository'),
  CatsRepository: Symbol('catsRepository')
}

class CatsService {
  constructor(
    private catsRepository: Repository<Cat>
  ) {}
}

@Module({
  providers: [
    {
      provide: InjectionTokens.DogsRepository,
      useClass: Repository
    },
    {
      provide: InjectionTokens.CatsRepository,
      useClass: Repository
    },
    {
      provide: CatsService,
      useFactory: (catsRepository: Repository<Cat>) =>
        new CatsService(catsRepository),
              /*Oops, wrong injection token...*/
      inject: [InjectionTokens.DogsRepository]
    }
  ],
})
export class Application {}

Now, let’s take a look at how you can create a CatsService with Clawject.

class CatsService {
  constructor(
    private catsRepository: Repository<Cat>
  ) {}
}

@ClawjectApplication
class Application {
  dogsRepository = Bean(Repository<Dog>);
  catsRepository = Bean(Repository<Cat>);

  catsService = Bean(CatsService);
}

And that’s it! ✨

Clawject will resolve all dependencies based on types and notify you of errors such as missing dependencies, circular dependencies, and more, at compile time and directly in your favorite IDE!

Clawject in-editor errors demonstration

Unleash the power of polymorphism with Clawject

Clawject works great with classes, interfaces, types, generics, and type inheritance, allowing you to describe dependencies very flexibly and simply.

Let’s declare an interface ReadOnlyRepository, interface Repository, and a class HttpRepository that implements both of these interfaces:

interface ReadOnlyRepository<T> { /*...*/ }

interface Repository<T> extends ReadOnlyRepository<T> { /*...*/ }

class HttpRepository<T> implements Repository<T> { /*...*/ }

We’ve created a polymorphic class and interfaces that allow reading and writing entities with the type .

Now, let’s declare the following services: ReadCatsService and WriteCatsService.

class ReadCatsService {
  constructor(
    private repository: ReadOnlyRepository<Cat>
  ) {}
}

class WriteCatsService {
  constructor(
    private repository: Repository<Cat>
  ) {}
}

As you can see, we simply state that we need dependencies of types ReadOnlyRepository and Repository, and we don’t care about the specific implementation that will be injected.

Now, let’s declare the Application class and our Beans.

@ClawjectApplication
class Application {
  httpCatsRepository = Bean(HttpRepository<Cat>);

  readCatsService = Bean(ReadCatsService);
  writeCatsService = Bean(WriteCatsService);
}

As you can see, Clawject understands that the class HttpRepository implements the interfaces ReadOnlyRepository and Repository, and will inject the httpCatsRepository bean instance as a dependency in both services.

If we were to do something similar with a more classical library, we would have to write a lot of boilerplate and non-type-safe code.

const InjectionTokens = {
  ReadOnlyCatsRepository: Symbol('ReadOnlyCatsRepository'),
  CatsRepository: Symbol('CatsRepository'),
  HttpCatsRepository: Symbol('HttpCatsRepository'),
}

@Injectable()
class ReadCatsService {
  constructor(
      @Inject(InjectionTokens.ReadOnlyCatsRepository)
      private repository: ReadOnlyRepository<Cat>
  ) {}
}

@Injectable()
class WriteCatsService {
  constructor(
      @Inject(InjectionTokens.CatsRepository)
      private repository: Repository<Cat>
  ) {}
}

@Module({
  providers: [
    {
      useClass: HttpRepository,
      provide: InjectionTokens.HttpCatsRepository,
    },
    {
      provide: InjectionTokens.ReadOnlyCatsRepository,
      useExisting: InjectionTokens.HttpCatsRepository,
    },
    {
      provide: InjectionTokens.CatsRepository,
      useExisting: InjectionTokens.HttpCatsRepository,
    },
    ReadCatsService,
    WriteCatsService,
  ],
})
class Application {}

Clean domain objects

The philosophy of Clawject revolves around the idea that dependency injection should be an external architectural layer, while all domain objects should describe their dependencies without any framework references.

Clawject allows you to extract absolutely all DI-related things from your classes, simplifying your code and reducing the probability of mistakes. Because Clawject is a very external component, you can work with any classes from external libraries just as easily as with your own.

Let’s imagine we have an npm package called data-access.

/* node_modules/data-access/repositories.d.ts */

export interface Repository<T> { /*...*/ }
export declare class HttpRepository<T> implements Repository<T> {
  private readonly baseUrl;
  constructor(baseUrl: string);
}

Now, let’s declare the CatsService that uses the repository from data-access package.

/* src/cat/CatsService.ts */

import { Repository } from 'data-access';
import { Cat } from './models/Cat';

class CatsService {
  constructor(
    private repository: Repository<Cat>
  ) {}
}

Now, let’s declare beans for our classes.

/* src/Application.ts */

import { HttpRepository } from 'data-access';
import { Cat } from './cat/models/Cat';
import { CatsService } from './cat/CatsService';

@ClawjectApplication
class Application {
  @Bean catsApiBaseUrl = '/api/cat';

  httpCatsRepository = Bean(HttpRepository<Cat>);
  catsService = Bean(CatsService);
}

As you can see, the classes remain clean and literally know nothing about being part of a dependency injection container. Moreover, you don’t need to manually write factory functions to keep your classes clean and framework-independent.

Split container by features

Clawject allows you to break down parts of the container into separate classes and even share them via npm packages.

Let’s declare the CatsConfiguration class, which will contain beans related only to cats.

@Configuration
export class CatsConfiguration {
  @Bean apiBaseUrl = '/api/cat';

  httpCatsRepository = Bean(HttpRepository<Cat>);
  catsService = Bean(CatsService);
}

Now we can import the configuration classes into our Application class or other configuration classes.

import { CatsConfiguration } from './cat/CatsConfiguration';
import { DogsConfiguration } from './dog/DogsConfiguration';
import { BirdsConfiguration } from './bird/BirdsConfiguration';

@ClawjectApplication
class Application {
  catsConfiguration = Import(CatsConfiguration);
  dogsConfiguration = Import(DogsConfiguration);
  birdsConfiguration = Import(BirdsConfiguration);
}

Clawject will assemble the entire container, instantiate all classes with the necessary dependencies, and inform you in a very developer-friendly manner if anything is missing.

Thanks for reading this article. If you’re interested, visit Clawject’s website for more examples and learn how to install and use it in your project.

The post Clawject: Simplifying Dependency Injection in TypeScript appeared first on ProdSens.live.

]]>
https://prodsens.live/2024/04/06/clawject-simplifying-dependency-injection-in-typescript/feed/ 0