Skip to content

Commit 9de5ea0

Browse files
authored
Merge pull request #42 from andrewlock/single-package-attempt-2
Remove StronglyTypedId.Attributes package
2 parents 33324ba + f101d65 commit 9de5ea0

File tree

30 files changed

+209
-311
lines changed

30 files changed

+209
-311
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Changelog
22

3+
## [v1.0.0-beta05]
4+
5+
Breaking Changes:
6+
* Removed StronglyTypedId.Attributes NuGet package.
7+
* The attributes are no longer embed in your project by default, instead it will use the external dll. You can re-enable the embedding by setting `STRONGLY_TYPED_ID_EMBED_ATTRIBUTES`.
8+
9+
New Features:
10+
11+
* Improved approach to handling [InternalsVisibleTo] issues, by embedding the StronglyTypedId.Attributes.dll in the NuGet package directly.
12+
313
## [v1.0.0-beta04]
414

515
New Features:

README.md

Lines changed: 89 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@ public partial struct FooId { }
1818

1919
and the source generator magically generates the backing code when you save the file! Use _Go to Definition_ to see the generated code:
2020

21-
<picture>
22-
<source srcset="https://raw.githubusercontent.com/andrewlock/StronglyTypedId/master/docs/strongly_typed_id.mp4" type="video/mp4">
23-
<img src="https://raw.githubusercontent.com/andrewlock/StronglyTypedId/master/docs/strongly_typed_id.gif" alt="Generating a strongly-typed ID using the StronglyTypedId packages"/>
24-
</picture>
21+
<img src="https://raw.githubusercontent.com/andrewlock/StronglyTypedId/master/docs/strongly_typed_id.gif" alt="Generating a strongly-typed ID using the StronglyTypedId packages"/>
2522

2623
> StronglyTypedId requires requires [the .NET Core SDK v6.0.100 or greater](https://dotnet.microsoft.com/download/dotnet/6.0).
2724
@@ -58,7 +55,15 @@ To use the the [StronglyTypedId NuGet package](https://www.nuget.org/packages/St
5855
* [Dapper](https://www.nuget.org/packages/Dapper/) (optional, only required if [generating a type mapper](https://andrewlock.net/using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-3/#interfacing-with-external-system-using-strongly-typed-ids))
5956
* [EF Core](https://www.nuget.org/packages/Microsoft.EntityFrameworkCore) (optional, only required if [generating an EF Core ValueConverter](https://andrewlock.net/strongly-typed-ids-in-ef-core-using-strongly-typed-entity-ids-to-avoid-primitive-obsession-part-4/))
6057

61-
To install the packages, add the references to your _csproj_ file so that it looks something like the following:
58+
To install the packages, add the references to your _csproj_ file, for example by running
59+
60+
```bash
61+
dotnet add package StronglyTypedId --version 1.0.0-beta05
62+
```
63+
64+
This adds a `<PackageReference>` to your project. You can additionally mark the package as `PrivateAsets="all"` and `ExcludeAssets="runtime"`.
65+
66+
> Setting `PrivateAssets="all"` means any projects referencing this one will not also get a reference to the _StronglyTypedId_ package. Setting `ExcludeAssets="runtime"` ensures the _StronglyTypedId.Attributes.dll_ file is not copied to your build output (it is not required at runtime).
6267
6368
```xml
6469
<Project Sdk="Microsoft.NET.Sdk">
@@ -68,8 +73,8 @@ To install the packages, add the references to your _csproj_ file so that it loo
6873
<TargetFramework>net6.0</TargetFramework>
6974
</PropertyGroup>
7075

71-
<!-- Core package -->
72-
<PackageReference Include="StronglyTypedId" Version="1.0.0-beta04" />
76+
<!-- Add the package -->
77+
<PackageReference Include="StronglyTypedId" Version="1.0.0-beta05" PrivateAssets="all" ExcludeAssets="runtime" />
7378
<!-- -->
7479

7580
</Project>
@@ -124,38 +129,100 @@ var id = new FooId("my-id-value");
124129
```
125130
Currently supported values are `Guid` (the default), `int`, `long`, and `string`.
126131

127-
## Error CS0436 and [InternalsVisibleTo]
132+
## Changing the defaults globally
128133

129-
The StronglyTypedId generator automatically adds the `[StronglyTypedId]` attributes to your compilation as `internal` attributes. If you add the source generator package to multiple projects, and use the `[InternalsVisibleTo]` attribute, you may experience errors when you build:
134+
If you wish to change the converters, backing types, or implementations used by default for _all_ the `[StronglyTypedId]`-decorated IDs in your project, you can use the assembly attribute `[StronglyTypedIdDefaults]` to set all of these. For example, the following sets the default converter to a whole project to `[SystemTextJson]`, and changes the default backing-type to an `int`
130135

131-
```bash
132-
warning CS0436: The type 'StronglyTypedIdImplementations' in 'StronglyTypedIds\StronglyTypedIds.StronglyTypedIdGenerator\StronglyTypedIdImplementations.cs' conflicts with the imported type 'StronglyTypedIdImplementations' in 'MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
136+
```csharp
137+
// Set the defaults for the project
138+
[assembly:StronglyTypedIdDefaults(
139+
backingType: StronglyTypedIdBackingType.Int,
140+
converters: StronglyTypedIdConverter.SystemTextJson)]
141+
142+
[StronglyTypedId]
143+
public partial struct OrderId { }
144+
145+
[StronglyTypedId]
146+
public partial struct UserId { }
147+
```
148+
149+
This is equivalent to setting these values manually on all the IDs:
150+
151+
```csharp
152+
[StronglyTypedId(
153+
backingType: StronglyTypedIdBackingType.Int,
154+
converters: StronglyTypedIdConverter.SystemTextJson)]
155+
public partial struct OrderId { }
156+
157+
[StronglyTypedId(
158+
backingType: StronglyTypedIdBackingType.Int,
159+
converters: StronglyTypedIdConverter.SystemTextJson)]
160+
public partial struct UserId { }
133161
```
134162

135-
Removing the `[InternalsVisibleTo]` attribute will resolve the problem, but if this is not possible you can disable the auto-generation of the `[StronglyTypedId]` marker attributes, and rely on the helper [`StronglyTypedId.Attributes` package instead](https://www.nuget.org/packages/StronglyTypedId.Attributes). This package contains the same attributes, but as they are in an external package, you can avoid the CS0436 error.
136163

137-
Add the package to your solution, ensuring you set `"PrivateAssets="All"` in the `<PackageReference>` (this will be done automatically when using the .NET CLI or an IDE). To disable the auto-generation of the marker attributes, define the constant `STRONGLY_TYPED_ID_EXCLUDE_ATTRIBUTES` in your project file. Your project file should look something like the following:
164+
## Embedding the attributes in your project
165+
166+
By default, the `[StronglyTypedId]` attributes referenced in your application are contained in an external dll. It is also possible to embed the attributes directly in your project, so they appear in the dll when your project is built. If you wish to do this, you must do two things:
167+
168+
1. Define the MSBuild constant `STRONGLY_TYPED_ID_EMBED_ATTRIBUTES`. This ensures the attributes are embedded in your project
169+
2. Add `compile` to the list of excluded assets in your `<PackageReference>` element. This ensures the attributes in your project are referenced, instead of the _StronglyTypedId.Attributes.dll_ library.
170+
171+
Your project file should look something like this:
138172

139173
```xml
140174
<Project Sdk="Microsoft.NET.Sdk">
141175

142176
<PropertyGroup>
143177
<OutputType>Exe</OutputType>
144178
<TargetFramework>net6.0</TargetFramework>
145-
<DefineConstants>STRONGLY_TYPED_ID_EXCLUDE_ATTRIBUTES</DefineConstants>
179+
<!-- Define the MSBuild constant -->
180+
<DefineConstants>STRONGLY_TYPED_ID_EMBED_ATTRIBUTES</DefineConstants>
146181
</PropertyGroup>
147-
148-
<!-- Core package -->
149-
<PackageReference Include="StronglyTypedId" Version="1.0.0-beta04" />
150-
<PackageReference Include="StronglyTypedId.Attributes" Version="1.0.0-beta04">
151-
<PrivateAssets>All</PrivateAssets>
152-
</PackageReference>
153-
<!-- -->
182+
183+
<!-- Add the package -->
184+
<PackageReference Include="StronglyTypedId" Version="1.0.0-beta05"
185+
PrivateAssets="all"
186+
ExcludeAssets="compile;runtime" />
187+
<!-- ☝ Add compile to the list of excluded assets. -->
154188

155189
</Project>
156190
```
157191

158-
The attribute library is only required at compile time, so it won't appear in your build output.
192+
## Preserving usages of the `[StronglyTypedId]` attribute
193+
194+
The `[StronglyTypedId]` and `[StronglyTypedIdDefaults]` attributes are decorated with the `[Conditional]` attribute, [so their usage will not appear in the build output of your project](https://andrewlock.net/conditional-compilation-for-ignoring-method-calls-with-the-conditionalattribute/#applying-the-conditional-attribute-to-classes). If you use reflection at runtime on one of your IDs, you will not find `[StronglyTypedId]` in the list of custom attributes.
195+
196+
If you wish to preserve these attributes in the build output, you can define the `STRONGLY_TYPED_ID_USAGES` MSBuild variable. Note that this means your project will have a runtime-dependency on _StronglyTypedId.Attributes.dll_ so you need to ensure this is included in your build output.
197+
198+
```xml
199+
<Project Sdk="Microsoft.NET.Sdk">
200+
201+
<PropertyGroup>
202+
<OutputType>Exe</OutputType>
203+
<TargetFramework>net6.0</TargetFramework>
204+
<!-- Define the MSBuild constant to preserve usages -->
205+
<DefineConstants>STRONGLY_TYPED_ID_USAGES</DefineConstants>
206+
</PropertyGroup>
207+
208+
<!-- Add the package -->
209+
<PackageReference Include="StronglyTypedId" Version="1.0.0-beta05" PrivateAssets="all" />
210+
<!-- ☝ You must not exclude the runtime assets in this case -->
211+
212+
</Project>
213+
```
214+
215+
## Error CS0436 and [InternalsVisibleTo]
216+
217+
> In the latest version of StronglyTypedId, you should not experience error CS0436 by default.
218+
219+
In previous versions of the StronglyTypedId generator, the `[StronglyTypedId]` attributes were added to your compilation as `internal` attributes by default. If you added the source generator package to multiple projects, and used the `[InternalsVisibleTo]` attribute, you could experience errors when you build:
220+
221+
```bash
222+
warning CS0436: The type 'StronglyTypedIdImplementations' in 'StronglyTypedIds\StronglyTypedIds.StronglyTypedIdGenerator\StronglyTypedIdImplementations.cs' conflicts with the imported type 'StronglyTypedIdImplementations' in 'MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
223+
```
224+
225+
In the latest version of _StronglyTypedId_, the attributes are not embedded by default, so you should not experience this problem. If you see this error, compare your installation to the examples in the installation guide.
159226

160227
## Why do I need this library?
161228

releasenotes.props

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@
55
66
Version 0.x of this library used the helper library CodeGeneration.Roslyn for build-time source generation. In version 1.x this approach has been completely replaced in favour of source generators, as these are explicitly supported in .NET 5+. As part of this change, there were a number of additional features added and breaking changes made.
77
8+
## Changes in 1.0.0-beta05:
9+
10+
Breaking Changes:
11+
* Removed StronglyTypedId.Attributes NuGet package.
12+
* The attributes are no longer embed in your project by default, instead it will use the external dll. You can re-enable the embedding by setting `STRONGLY_TYPED_ID_EMBED_ATTRIBUTES`.
13+
14+
New Features:
15+
16+
* Improved approach to handling [InternalsVisibleTo] issues, by embedding the StronglyTypedId.Attributes.dll in the NuGet package directly.
17+
818
## Changes in 1.0.0-beta04:
919
1020
New Features:
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>net461;netstandard2.0;netcoreapp2.1</TargetFrameworks>
4+
<TargetFramework>netstandard2.0</TargetFramework>
55
<Nullable>enable</Nullable>
66
<RootNamespace>StronglyTypedIds</RootNamespace>
7-
<PackageId>StronglyTypedId.Attributes</PackageId>
8-
<Description>Helper library for StronglyTypedId generator containg attributes only. See README for when to use this package </Description>
9-
<IsPackable>true</IsPackable>
7+
<IsPackable>false</IsPackable>
108
</PropertyGroup>
119

1210
</Project>

src/StronglyTypedIds/EmbeddedSources.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ namespace StronglyTypedIds
88
internal static class EmbeddedSources
99
{
1010
private static readonly Assembly ThisAssembly = typeof(EmbeddedSources).Assembly;
11-
internal static readonly string StronglyTypedIdAttributeSource = LoadEmbeddedResource("StronglyTypedIds.Templates.Sources.StronglyTypedIdAttribute.cs");
12-
internal static readonly string StronglyTypedIdDefaultsAttributeSource = LoadEmbeddedResource("StronglyTypedIds.Templates.Sources.StronglyTypedIdDefaultsAttribute.cs");
13-
internal static readonly string StronglyTypedIdBackingTypeSource = LoadEmbeddedResource("StronglyTypedIds.Templates.Sources.StronglyTypedIdBackingType.cs");
14-
internal static readonly string StronglyTypedIdConverterSource = LoadEmbeddedResource("StronglyTypedIds.Templates.Sources.StronglyTypedIdConverter.cs");
15-
internal static readonly string StronglyTypedIdImplementationsSource = LoadEmbeddedResource("StronglyTypedIds.Templates.Sources.StronglyTypedIdImplementations.cs");
11+
internal static readonly string StronglyTypedIdAttributeSource = LoadTemplateForEmitting("StronglyTypedIdAttribute");
12+
internal static readonly string StronglyTypedIdDefaultsAttributeSource = LoadTemplateForEmitting("StronglyTypedIdDefaultsAttribute");
13+
internal static readonly string StronglyTypedIdBackingTypeSource = LoadTemplateForEmitting("StronglyTypedIdBackingType");
14+
internal static readonly string StronglyTypedIdConverterSource = LoadTemplateForEmitting("StronglyTypedIdConverter");
15+
internal static readonly string StronglyTypedIdImplementationsSource = LoadTemplateForEmitting("StronglyTypedIdImplementations");
1616

1717
private static readonly string AutoGeneratedHeader = LoadEmbeddedResource("StronglyTypedIds.Templates.AutoGeneratedHeader.cs");
1818

@@ -128,5 +128,17 @@ public ResourceCollection(
128128
Header = header;
129129
}
130130
}
131+
132+
internal static string LoadTemplateForEmitting(string resourceName)
133+
{
134+
var resource = LoadEmbeddedResource($"StronglyTypedIds.Templates.Sources.{resourceName}.cs");
135+
return AutoGeneratedHeader + @"#if STRONGLY_TYPED_ID_EMBED_ATTRIBUTES
136+
137+
" + resource
138+
.Replace("public sealed", "internal sealed")
139+
.Replace("public enum", "internal enum")
140+
+ @"
141+
#endif";
142+
}
131143
}
132144
}

src/StronglyTypedIds/Parser.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using Microsoft.CodeAnalysis.CSharp;
77
using Microsoft.CodeAnalysis.CSharp.Syntax;
88
using StronglyTypedIds.Diagnostics;
9-
using StronglyTypedIds.Sources;
109

1110
namespace StronglyTypedIds;
1211

src/StronglyTypedIds/SourceGenerationHelper.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Text;
4-
using StronglyTypedIds.Sources;
54

65
namespace StronglyTypedIds
76
{

src/StronglyTypedIds/Sources/StronglyTypedIdAttribute.cs

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/StronglyTypedIds/Sources/StronglyTypedIdBackingType.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/StronglyTypedIds/Sources/StronglyTypedIdConverter.cs

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)