我建议另一种方式。从服务器项目引用WASM项目还存在其他缺点,但个人认为这是一个架构上不优雅的解决方案。
Blazor Server和WASM在以下关键领域存在差异:
1.身份验证:Blazor Server允许您在运行时自定义对特定区域的访问。在WASM中,授权一次性完成,并将应用程序代码完全发送。
2.数据库访问:Blazor Server允许直接访问EF Core实体(因为代码仅在服务器上执行)。在Blazor中,实际上不可能直接访问任何数据库。这也是高度不鼓励的,因为您会将连接字符串发送到客户端。因此,需要编写单独的Web API来访问数据。
3.设置文件:您可以在服务器端Blazor中拥有尽可能多的设置文件。客户端Blazor默认仅加载appsettings.json。需要使用特殊机制才能包含多个.json文件。
因此,对于大多数应用程序(尤其是需要访问数据库的应用程序),您将无法在WASM和服务器端之间共享100%的代码库。
以下是您应该采取的替代方法:
针对上述提到的问题(主要是认证,但大部分是数据库访问),创建一个数据访问服务依赖项(比如IDataAccessLayer)。
一个实现将直接访问数据库(用于服务器端),另一个实现将通过HttpClient访问数据库(用于Blazor WASM)。
现在,将整个应用程序放入一个RCL中。将其命名为“BlazorAppRCL”。这个RCL显然没有Startup.cs和Program.cs。
为服务器和客户端特定的数据库访问实现创建一个项目。
现在,您有以下一组项目:
对于服务器端:
BlazorServer(仅具有设置+Program.cs+Startup.cs)。它引用了RCL+ IDataAccessLayer 的服务器特定实现
对于托管的WASM:
BlazorWebAPI:用于访问数据库,它具有访问数据库的API
BlazorClientDAL:WASM特定的IDataAccessLayer实现
BlazorWASM:Blazor WASM项目
所有三个都引用了您的BlazorAppRCL。
关键是使用DI /控制反转模式来解决WASM和服务器之间的差异。通过这种方式,您可以拥有两个实例:WASM实例和服务器实例,而代码差异最小。请注意,WASM WebAPI可以简单地使用服务器端Blazor的IDataAccessLayer实现。因此,除了与API相关的开销外,不需要进行额外的编码。