求生欲:仅自己想的一个解决方法,如有不妥之处,还望大家不吝赐教,及时纠正我。
正文开始:
工厂方式创建对象,无非是想根据不同的参数获取到创建的不同对象。
先抛一个结论,kratos框架中,data(包)层会依赖于biz(包)层。
下面这段伪代码方法是写在biz包的一个UseCase.go中,而NewIosP8(xx,xx)是属于data包的xxx,所以在此处就有了biz包依赖data包,在结合上面的结论。
func (cuc *CertificateUseCase) GetCerInter(Type string) CertificateRepo {
switch Type {
case constant.IOS_P8:
return data.NewIosP8(xx,xx);
default:
return nil
}
}
问题:go中不允许不同的包相互依赖,因此编译启动项目时会报循环依赖的错误。
解决:kratos中使用了wire的编译时依赖注入,将UseCase.go中所有这个方法可能创建出来的对象都提前创建出来,并关联到这个UseCase下,如下图:
func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) {
dataData, err := data.NewData(confData, logger)
if err != nil {
return nil, nil, err
}
parentCertificateRepo := data.NewParentCertificateRepo(dataData, logger)
iosP8CertificateRepo := data.NewIosP8Certificate(dataData)
iosPCertificateRepo := data.NewIosPCertificate(dataData)
andHuaweiCertificateRepo := data.NewAndHuaweiCertificate(dataData)
andMeizuCertificateRepo := data.NewAndMeizuCertificate(dataData)
miAndGoogleRepo := data.NewMiAndGoogle(dataData)
andOppoCertificateRepo := data.NewAndOppoCertificate(dataData)
andVivoCertificateRepo := data.NewAndVivoCertificate(dataData)
certificateUseCase := biz.NewCertificateUseCase(parentCertificateRepo, andHuaweiCertificateRepo, iosPCertificateRepo, iosP8CertificateRepo, andMeizuCertificateRepo, miAndGoogleRepo, andOppoCertificateRepo, andVivoCertificateRepo, logger)
certificateService := service.NewCertificateService(certificateUseCase)
grpcServer := server.NewGRPCServer(confServer, appService, certificateService, imUserStaticService, userService, clientAppService, logger)
app := newApp(logger, grpcServer)
return app, func() {
//cleanup()
}, nil
}
创建certificateUseCase的时候将前面创建好的xxxRepo都关联进去。后面的工厂方法就可以这样写了,如下图:
func (cuc *CertificateUseCase) GetCerInter(Type string) CertificateRepo {
switch Type {
case constant.IOS_P8:
return cuc.iosP8
case constant.IOS_P12, constant.IOS_Push_Kit:
return cuc.ios
case constant.MI, constant.Google:
return cuc.miAndGoogle
case constant.HuaWei:
return cuc.huawei
case constant.MeiZu:
return cuc.meizu
case constant.VivoAnd:
return cuc.vivo
case constant.OppoAnd:
return cuc.oppo
default:
return nil
}
}
我们只需要将已经创建好的对象根据传入的不同Type值直接返回即可。