Skip to main content

Creator[T] interface

type Creator[T] interface {
New(ctx context.Context) (T, context.Context)
}

In order to instruct Ore to use Creator[T] to build and initialize new instances of service T, make sure that your service's struct implements Creator[T] :

Example Usage

type Counter interface {
GetCount() int
AddOne()
}

type simpleCounterImpl struct {
counter int
}

// implementing Creator[T]
func (c *simpleCounterImpl) New(ctx context.Context) (Counter, context.Context) {
return &simpleCounterImpl{
counter: 0
}, ctx
}

func (c *simpleCounterImpl) AddOne() {
c.counter += 1
}

func (c *simpleCounterImpl) GetCount() int {
return c.counter
}

Registering Creator[T] service

ore.RegisterCreator[Counter](ore.Scoped, &simpleCounterImpl{})

Note that here we used ore.RegisterCreator instead of ore.RegisterFunc.

Resolving Creator[T] service

counterService, ctx := ore.Get[Counter](context.Background())

Sample Service

let's define a NotificationService that sends a notification to a user via Email and SMS:

// EmailProvider defines the interface for sending emails.
type EmailProvider interface {
SendEmail(to string, subject string, body string) error
}

// SmsProvider defines the interface for sending SMS messages.
type SmsProvider interface {
SendSms(to string, message string) error
}

// NotificationService defines the interface for notifying users.
type NotificationService interface {
NotifyUser(email string, phone string, message string) error
}

note that NotificationService logically depends on EmailProvider and SmsProvider

type smtpEmailProvider struct {
host string
port int
username string
password string
}

// implementing `Creator[T]`
func (m *smtpEmailProvider) New(ctx context.Context) (EmailProvider, context.Context) {
return &smtpEmailProvider{
host: "smtp.gmail.com",
port: 587,
username: "someemailaddress@gmail.com",
password: "somepasswordhere",
}, ctx
}

func (m *smtpEmailProvider) connect() (SMTPConnection, error) {
// connect to SMTP server
}

func (m *smtpEmailProvider) send(conn SMTPConnection, to string, subject string, body string) error {
// send an email via SMTP server connection
conn.Send(to, subject, body)
}

func (m *smtpEmailProvider) SendEmail(to string, subject string, body string) error {
// connect to SMTP server
conn, err := m.connect(m.host, m.port, m.username, m.password)
err = m.send(conn, to, subject, body)

return err
}
type smsGatewayProvider struct {
apiUrl string
apiKey string
}

// implementing `Creator[T]`
func (m *smsGatewayProvider) New(ctx context.Context) (SmsProvider, context.Context) {
return &smsGatewayProvider{
apiUrl: "https://gateway.somesmsprovider.com",
apiKey: "1f7b3bb5-ce07-4119-864d-0995f6f89515",
}, ctx
}

func (m *smsGatewayProvider) SendSms(to string, message string) error {
someSmsSender.Send(m.apiUrl, m.apiKey, to, message)

return err
}
type userNotifier struct {
emailProvider EmailProvider
smsProvider SmsProvider
}

// implementing `Creator[T]`
func (un *userNotifier) New(ctx context.Context) (NotificationService, context.Context) {
emailProviderService, ctx := ore.Get[EmailProvider](ctx)
smsProviderService, ctx := ore.Get[SmsProvider](ctx)

return &userNotifier{
emailProvider: emailProviderService,
smsProvider: smsProviderService,
}, ctx
}

func (un *userNotifier) NotifyUser(email string, phone string, message string) error {
err := un.emailProvider.SendEmail(email, "Notification", message)
err = un.smsProvider.SendSms(phone, message)

return err
}

Register Services via Creator[T] (RegisterCreator)

registering EmailProvider service:

ore.RegisterCreator[EmailProvider](ore.Scoped, &smtpEmailProvider{})

registering SmsProvider service:

ore.RegisterCreator[SmsProvider](ore.Scoped, &smsGatewayProvider{})

registering NotificationService service:

ore.RegisterCreator[NotificationService](ore.Scoped, &userNotifier{})