我正在开发一个系统,其中有一个基础项目(让我们称之为项目A
),这是一个类库。它包含我可以很容易地将其用于未来项目的通用实体,控制器,中间件等。我有一个项目B
,它依赖于基础库A
,以便继承其常用功能。将来,项目C,D,E,F ......都将取决于基础项目A
。
我的基础库A
中的几乎所有实体都需要与用户实体建立关系。例如,我的基础库将有一个Notification
实体,该实体需要与通知所针对的User
建立关系。但是,用户实体在项目A
中定义,因为每个项目可以在用户上具有不同的特征和字段(所有项目都将继承IdentityUser
)
项目B
中的用户定义可能如下所示......
namespace B
{
public class User : IdentityUser
{
[Required]
[StringLength(100, ErrorMessage = "The {0} must max {1} characters long.")]
[Display(Name = "First Name")]
public string FirstName { get; set; }
//omitted for brevity
}
}
现在考虑我的基础项目A
中的一个类。
namespace A
{
public class Notification<TUser>
where TUser : IdentityUser
{
//User who this notification is for
public TUser Owner { get; set; }
}
}
我已经将我的所有实体和存储库都设为通用的,因此我基本上可以从任何后续项目B,C,D,E,F中将所需的任何用户实体注入到框架中。
经过几个小时的尝试,这一切都归结为一个问题。在我的基础项目A
中假设我有一个控制器来查看通知。
namespace A
{
public class NotificationController<TUser> : BaseController
{
private readonly INotificationRepository<TUser> _notificationRepository;
public NotificationController(INotificationRepository<TUser> notificationRepository)
{
_notificationRepository = notificationRepository;
}
public async Task<IActionResult> GetAllNotifications()
{
var notifications = await _notificationRepository.GetNotificationsAsync();
return Json(notifications);
}
}
}
通常,在我的项目B
中,我可以使用以下内容注册库A
中定义的控制器:
services.AddMvc()
...
.AddApplicationPart(typeof(A.NotificationController).Assembly);
但是,这似乎不适用于通用控制器。理想情况下,我会做这样的事情
services.AddMvc()
...
.AddApplicationPart(typeof(A.NotificationController<User>).Assembly); //Where User is the User defined in project B
这不起作用,控制器操作都是错误404.我被迫以另一种方式做到这一点。我必须在项目B中创建一个虚拟控制器,它充当包装器:
namespace B
{
public class NotificationController : A.NotificationController<User>
{
public NotificationController(INotificationRepository<User> notificationRepository)
: base(notificationRepository)
{
}
}
}
在项目B
中拥有此控制器意味着它被MVCCore选中,并且可以正确填写Controller和存储库的泛型。使用这种方法,一切都可以完美地编译和运行,但我想知道是否有更简单的方法可以做到这一点,或者我做错了什么。
我做事的方式对我来说似乎很复杂,但是自从我使用静态类型的语言完成任何主要工作以来,这也是多年,所以也许没有更好的方法。
我认为这个问题在这里是最合适的,但如果这类问题不适合stackoverflow,请建议一个更合适的社区(codereview或softwareengineering)。