Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ type factoryServiceMaping struct {
Service ServiceDef
}

type factoryService interface {
Factory() any
MustFactory() any
}

// Container is responsible for storing services, instances and the dependency graph
type Container struct {
pal *Pal
Expand All @@ -45,13 +50,22 @@ func NewContainer(pal *Pal, services ...ServiceDef) *Container {

for _, service := range services {
container.addService(service)
if factorier, ok := service.(interface{ Factory() any }); ok {
fn := factorier.Factory()
if factory, ok := service.(factoryService); ok {
// Add Factory to the container
fn := factory.Factory()
fnType := reflect.TypeOf(fn)
container.factories[typetostring.GetReflectType(fnType)] = factoryServiceMaping{
Factory: fn,
Service: service,
}

// Add MustFactory to the container
fn = factory.MustFactory()
fnType = reflect.TypeOf(fn)
container.factories[typetostring.GetReflectType(fnType)] = factoryServiceMaping{
Factory: fn,
Service: service,
}
}
}

Expand Down
10 changes: 10 additions & 0 deletions service_factory0.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ func (c *ServiceFactory0[I, T]) Instance(ctx context.Context, _ ...any) (any, er
}

// Factory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context) (I, error).
func (c *ServiceFactory0[I, T]) Factory() any {
return func(ctx context.Context) (I, error) {
instance, err := c.Instance(ctx)
Expand All @@ -37,3 +38,12 @@ func (c *ServiceFactory0[I, T]) Factory() any {
return instance.(I), nil
}
}

// MustFactory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context) I.
// If the instance creation fails, it panics.
func (c *ServiceFactory0[I, T]) MustFactory() any {
return func(ctx context.Context) I {
return must(c.Instance(ctx)).(I)
}
}
10 changes: 10 additions & 0 deletions service_factory1.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func (c *ServiceFactory1[I, T, P1]) Instance(ctx context.Context, args ...any) (
}

// Factory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1) (I, error).
func (c *ServiceFactory1[I, T, P1]) Factory() any {
return func(ctx context.Context, p1 P1) (I, error) {
instance, err := c.Instance(ctx, p1)
Expand All @@ -47,3 +48,12 @@ func (c *ServiceFactory1[I, T, P1]) Factory() any {
return instance.(I), nil
}
}

// MustFactory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1) I.
// If the instance creation fails, it panics.
func (c *ServiceFactory1[I, T, P1]) MustFactory() any {
return func(ctx context.Context, p1 P1) I {
return must(c.Instance(ctx, p1)).(I)
}
}
26 changes: 25 additions & 1 deletion service_factory1_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ type serviceWithFactoryServiceDependency struct {
}

type serviceWithFactoryFunctionDependency struct {
CreateDependency func(ctx context.Context, name string) (*factory1Service, error)
CreateDependency func(ctx context.Context, name string) (*factory1Service, error)
MustCreateDependency func(ctx context.Context, name string) *factory1Service
}

// TestService_Instance tests the Instance method of the service struct
Expand Down Expand Up @@ -130,4 +131,27 @@ func TestServiceFactory1_Invocation(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "test", dependency.Name)
})

t.Run("when invoked via injected must factory function, returns a new instance built with given arguments", func(t *testing.T) {
t.Parallel()

service := pal.ProvideFactory1[*factory1Service](func(_ context.Context, name string) (*factory1Service, error) {
return &factory1Service{Name: name}, nil
})
p := newPal(service)

ctx := pal.WithPal(t.Context(), p)

err := p.Init(t.Context())
assert.NoError(t, err)

serviceWithFactoryFn := &serviceWithFactoryFunctionDependency{}
err = p.InjectInto(ctx, serviceWithFactoryFn)

assert.NoError(t, err)

dependency := serviceWithFactoryFn.MustCreateDependency(ctx, "test")

assert.Equal(t, "test", dependency.Name)
})
}
10 changes: 10 additions & 0 deletions service_factory2.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func (c *ServiceFactory2[I, T, P1, P2]) Instance(ctx context.Context, args ...an
}

// Factory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context) (I, error).
func (c *ServiceFactory2[I, T, P1, P2]) Factory() any {
return func(ctx context.Context, p1 P1, p2 P2) (I, error) {
instance, err := c.Instance(ctx, p1, p2)
Expand All @@ -52,3 +53,12 @@ func (c *ServiceFactory2[I, T, P1, P2]) Factory() any {
return instance.(I), nil
}
}

// MustFactory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1, p2 P2) I.
// If the instance creation fails, it panics.
func (c *ServiceFactory2[I, T, P1, P2]) MustFactory() any {
return func(ctx context.Context, p1 P1, p2 P2) I {
return must(c.Instance(ctx, p1, p2)).(I)
}
}
10 changes: 10 additions & 0 deletions service_factory3.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func (c *ServiceFactory3[I, T, P1, P2, P3]) Instance(ctx context.Context, args .
}

// Factory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1, p2 P2, p3 P3) (I, error).
func (c *ServiceFactory3[I, T, P1, P2, P3]) Factory() any {
return func(ctx context.Context, p1 P1, p2 P2, p3 P3) (I, error) {
instance, err := c.Instance(ctx, p1, p2, p3)
Expand All @@ -57,3 +58,12 @@ func (c *ServiceFactory3[I, T, P1, P2, P3]) Factory() any {
return instance.(I), nil
}
}

// MustFactory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1, p2 P2, p3 P3) I.
// If the instance creation fails, it panics.
func (c *ServiceFactory3[I, T, P1, P2, P3]) MustFactory() any {
return func(ctx context.Context, p1 P1, p2 P2, p3 P3) I {
return must(c.Instance(ctx, p1, p2, p3)).(I)
}
}
10 changes: 10 additions & 0 deletions service_factory4.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func (c *ServiceFactory4[I, T, P1, P2, P3, P4]) Instance(ctx context.Context, ar
}

// Factory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) (I, error).
func (c *ServiceFactory4[I, T, P1, P2, P3, P4]) Factory() any {
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) (I, error) {
instance, err := c.Instance(ctx, p1, p2, p3, p4)
Expand All @@ -62,3 +63,12 @@ func (c *ServiceFactory4[I, T, P1, P2, P3, P4]) Factory() any {
return instance.(I), nil
}
}

// MustFactory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) I.
// If the instance creation fails, it panics.
func (c *ServiceFactory4[I, T, P1, P2, P3, P4]) MustFactory() any {
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) I {
return must(c.Instance(ctx, p1, p2, p3, p4)).(I)
}
}
10 changes: 10 additions & 0 deletions service_factory5.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ func (c *ServiceFactory5[I, T, P1, P2, P3, P4, P5]) Instance(ctx context.Context
}

// Factory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) (I, error).
func (c *ServiceFactory5[I, T, P1, P2, P3, P4, P5]) Factory() any {
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) (I, error) {
instance, err := c.Instance(ctx, p1, p2, p3, p4, p5)
Expand All @@ -67,3 +68,12 @@ func (c *ServiceFactory5[I, T, P1, P2, P3, P4, P5]) Factory() any {
return instance.(I), nil
}
}

// MustFactory returns a function that creates a new instance of the service.
// The returned function has the signature func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) I.
// If the instance creation fails, it panics.
func (c *ServiceFactory5[I, T, P1, P2, P3, P4, P5]) MustFactory() any {
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) I {
return must(c.Instance(ctx, p1, p2, p3, p4, p5)).(I)
}
}