go语言使用kratos框架,使用工厂模式创建对象时,biz层和data层出现循环依赖的错误解决方案

求生欲:仅自己想的一个解决方法,如有不妥之处,还望大家不吝赐教,及时纠正我。

正文开始:

工厂方式创建对象,无非是想根据不同的参数获取到创建的不同对象。

先抛一个结论,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值直接返回即可。

你可能感兴趣的:(go,kratos,golang)