从两个可交换 class 库继承
Inheritance from two swappable class libraries
C# 解决方案结构
- 项目
ApiReduced
:一个class 库,包含一个由工具生成的文件Reference.cs
。它包含许多部分 classes,其中大部分继承自另一个 .NET class,例如class ODataService
继承自 DataServiceContext
。 classes 都在同一个命名空间 Som
.
- 项目
ApiFull
:Class 库与 ApiReduced
相同,但包含更多部分 classes,classes 具有更多属性等。想想它作为 ApiReduced
的超集。同样,在相同的命名空间下 Som
.
- 项目
ApiExtensions
:包含 Extensions.cs
,应该是(尚未决定继承或扩展方法是否最有意义)
- 继承自
ODataService
class 或
- 为 项目
ApiReduced
或 ApiFull
中的 classes 提供扩展方法
- 项目
MyProject
:包含引用项目ApiReduced
或ApiFull
的代码。此外,它引用 ApiExtensions
.
想要的效果
我想用上面的方法完成的是能够在 MyProject
中决定使用什么 API (完整或减少),这取决于我是否添加对 [=11 的引用=] 或 ApiFull
。实际上我有几个项目,有些应该使用完整的 API,有些应该使用简化的 API,但我希望在任何一种情况下都能够使用相同的扩展以避免代码重复。
我试过的
当我在ApiExtensions
中同时引用ApiReduced
和ApiFull
时,我自然会得到很多错误,即Reference.cs
中定义的类型在两个库中都存在。另一方面,如何在不引用 ApiReduced
或 ApiFull
中的至少一个的情况下实现 Extensions.cs
?如果我做出选择,那似乎是相当随意的。
TL;DR
我如何在使用两个几乎相同的 class 库(从某种意义上说,它们在同一命名空间中定义了部分 class 具有相同名称的部分)之间交换我的扩展 methods/derived class?
我建议您将扩展分为 ApiReducedExtensions
和 ApiFullExtensions
。
这样,当您想在项目中使用 Reduced API 时,您可以包含 ApiReduced
和 ApiReducedExtensions
而当您只想使用 FullApi 时,您只需要包含 ApiFull
和 ApiFullExtensions
编辑
为避免两者之间出现重复代码,您可以添加另一个 class ApiSharedExtensions
,其中包含两者的共同代码。 Api
也一样
简答:接口和依赖注入!
任何你想添加扩展的行为都应该基于一个接口,然后你在你的 Full 和 Reduced api classes 中实现这个接口。您的扩展程序集应该仅 引用接口程序集并适当地添加扩展。此时你的程序集看起来像
- ApiFull(引用 ApiInterfaces)
- ApiReduced(引用 ApiInterfaces)
- ApiExtensions(引用 ApiInterfaces)
- Api 接口
- MyProject(引用 ApiExtensions、ApiInterfaces 和 ApiFull 或 ApiReduced)
然后在您的项目中,您再次仅针对接口进行编码,这样您就可以根据需要使用扩展。在这个项目中,您使用依赖注入来注入正确的具体 class(来自 ApiFull 或 ApiReduced)
没有代码示例的答案是不完整的。因此,向接口添加扩展:
using System;
public class Program
{
public static void Main()
{
var foo = new Foo();
Console.WriteLine(foo.SayHello());
}
}
public static class INamedExtensions
{
public static string SayHello(this INamed named)
{
return $"Hello from {named.Name}";
}
}
public class Foo : INamed
{
public string Name {get => "Foo";}
}
public interface INamed
{
string Name{get;}
}
C# 解决方案结构
- 项目
ApiReduced
:一个class 库,包含一个由工具生成的文件Reference.cs
。它包含许多部分 classes,其中大部分继承自另一个 .NET class,例如classODataService
继承自DataServiceContext
。 classes 都在同一个命名空间Som
. - 项目
ApiFull
:Class 库与ApiReduced
相同,但包含更多部分 classes,classes 具有更多属性等。想想它作为ApiReduced
的超集。同样,在相同的命名空间下Som
. - 项目
ApiExtensions
:包含Extensions.cs
,应该是(尚未决定继承或扩展方法是否最有意义)- 继承自
ODataService
class 或 - 为 项目
ApiReduced
或ApiFull
中的 classes 提供扩展方法
- 继承自
- 项目
MyProject
:包含引用项目ApiReduced
或ApiFull
的代码。此外,它引用ApiExtensions
.
想要的效果
我想用上面的方法完成的是能够在 MyProject
中决定使用什么 API (完整或减少),这取决于我是否添加对 [=11 的引用=] 或 ApiFull
。实际上我有几个项目,有些应该使用完整的 API,有些应该使用简化的 API,但我希望在任何一种情况下都能够使用相同的扩展以避免代码重复。
我试过的
当我在ApiExtensions
中同时引用ApiReduced
和ApiFull
时,我自然会得到很多错误,即Reference.cs
中定义的类型在两个库中都存在。另一方面,如何在不引用 ApiReduced
或 ApiFull
中的至少一个的情况下实现 Extensions.cs
?如果我做出选择,那似乎是相当随意的。
TL;DR
我如何在使用两个几乎相同的 class 库(从某种意义上说,它们在同一命名空间中定义了部分 class 具有相同名称的部分)之间交换我的扩展 methods/derived class?
我建议您将扩展分为 ApiReducedExtensions
和 ApiFullExtensions
。
这样,当您想在项目中使用 Reduced API 时,您可以包含 ApiReduced
和 ApiReducedExtensions
而当您只想使用 FullApi 时,您只需要包含 ApiFull
和 ApiFullExtensions
编辑
为避免两者之间出现重复代码,您可以添加另一个 class ApiSharedExtensions
,其中包含两者的共同代码。 Api
简答:接口和依赖注入!
任何你想添加扩展的行为都应该基于一个接口,然后你在你的 Full 和 Reduced api classes 中实现这个接口。您的扩展程序集应该仅 引用接口程序集并适当地添加扩展。此时你的程序集看起来像
- ApiFull(引用 ApiInterfaces)
- ApiReduced(引用 ApiInterfaces)
- ApiExtensions(引用 ApiInterfaces)
- Api 接口
- MyProject(引用 ApiExtensions、ApiInterfaces 和 ApiFull 或 ApiReduced)
然后在您的项目中,您再次仅针对接口进行编码,这样您就可以根据需要使用扩展。在这个项目中,您使用依赖注入来注入正确的具体 class(来自 ApiFull 或 ApiReduced)
没有代码示例的答案是不完整的。因此,向接口添加扩展:
using System;
public class Program
{
public static void Main()
{
var foo = new Foo();
Console.WriteLine(foo.SayHello());
}
}
public static class INamedExtensions
{
public static string SayHello(this INamed named)
{
return $"Hello from {named.Name}";
}
}
public class Foo : INamed
{
public string Name {get => "Foo";}
}
public interface INamed
{
string Name{get;}
}