-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Lifecycle.ContainerChildScoped scope #203
Comments
I am trying to something similar where I have @injectable()
class ProjectOfferingsRepository {}
@injectable()
class ParentPageStore {
children: ChildStore[] = [];
constructor(private _projectOfferingsRepository: ProjectOfferingsRepository) {}
}
@injectable()
class ChildStore {
constructor(private _projectOfferingsRepository: ProjectOfferingsRepository) {}
} I thought about create a child container so I could make const parentPageStoreContainer = container.createChildContainer();
parentPageStoreContainer.registerSingleton(ProjectOfferingsRepository); Is there a way to have the store inject the injectables from the @useContainer(parentPageStoreContainer)
@injectable()
class ParentPageStore {
children: ChildStore[] = [];
constructor(private _projectOfferingsRepository: ProjectOfferingsRepository) {}
}
@useContainer(parentPageStoreContainer)
@injectable()
class ChildStore {
constructor(private _projectOfferingsRepository: ProjectOfferingsRepository) {}
} |
My question above is still valid but this what I did in the meantime until there is a different/better solution. I am open to suggestion on how to make this better. @injectable()
class ProjectOfferingsRepository {}
@injectable()
class RateCardRolesRepository {}
/**
* Some page store have children store(s) and they need to have access to the same repository(s),
* so we create a child D.I. container that holds on to a singleton version of those repository(s).
*
* We should clean up the child D.I. container when we leave the page {@see ParentPageStore.destroy}
*/
const parentPageStoreContainer: IDependencyContainer<
ProjectOfferingsRepository | RateCardRolesRepository
> = container
.createChildContainer()
.registerSingleton(ProjectOfferingsRepository)
.registerSingleton(RateCardRolesRepository);
@injectable()
class ParentPageStore {
private readonly _projectOfferingsRepository = parentPageStoreContainer.resolve(ProjectOfferingsRepository);
private readonly _rateCardRolesRepository = parentPageStoreContainer.resolve(RateCardRolesRepository);
children: ChildStore[] = [];
constructor() {}
destroy(): void {
parentPageStoreContainer.clearInstances();
}
}
@injectable()
class ChildStore {
private readonly _projectOfferingsRepository = parentPageStoreContainer.resolve(ProjectOfferingsRepository);
private readonly _rateCardRolesRepository = parentPageStoreContainer.resolve(RateCardRolesRepository);
constructor() {}
} I also created an interface so I could provide extra type safety with working with child containers. Also, I am open to suggestion on how to make this better. /**
* Created this interface, to enforce the correct types because the 'DependencyContainer' interface in
* `tsyringe` is not a generic.
*/
export default interface IDependencyContainer<U> extends Omit<DependencyContainer, 'resolve'> {
resolve<T extends U>(token: InjectionToken<T>): T;
} |
When working with tsyringe I've found the need for a scope that would allow me to use the same instance for a parent + all their childs. This is already possible by registering a singleton on a container, which will then also be used for all child containers.
The problem I'm facing with this is that I would need to manually register all classes inside the child container as a singleton to not share the instances through the root container. If I would define them with
@scoped(Lifecycle.ContainerScoped)
it would not work with the child containers, if I would define them with@singleton()
the instances would be shared across agents.Description
Not 100% sure what needs to happen, but by testing a bit locally I was able to use
@singleton()
and manually contstructing newInternalDependencyContainer
containers. This is not exposed, but just to get it working as I would like it to work.This way I have two containers that are always separated, but because the classes are defined as singleton, they will share the containers with their children.
Maybe we can add a way to create a new parent and decorate classes with
@scoped(Lifecycle.ContainerChildScoped)
?Alternate solutions
An alternate solution would be to expose the
InternalDependencyContainer
class and allow me to usesingleton
. This way there doesn't really need to be any code changed.Additional context
The text was updated successfully, but these errors were encountered: