Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Design;

/// <summary>
/// Design-time <see cref="MethodCallCodeFragment"/> extensions.
/// </summary>
public static class MethodCallCodeFragmentExtensions
{
/// <summary>
/// Gets the using statements required for this method call.
/// </summary>
/// <param name="methodCall">The method call.</param>
/// <returns>The usings.</returns>
public static IEnumerable<string> GetRequiredUsings(this MethodCallCodeFragment methodCall)
{
var method = methodCall.MethodInfo;
if (method?.IsStatic == true)
{
yield return method.DeclaringType!.Namespace!;
}

foreach (var argument in methodCall.Arguments)
{
if (argument is NestedClosureCodeFragment nestedClosure)
{
foreach (var nestedUsing in nestedClosure.MethodCalls.SelectMany(GetRequiredUsings))
{
yield return nestedUsing;
}
}
else if (argument is not null)
{
yield return argument.GetType().Namespace!;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,11 @@ public virtual string TransformText()

}

var useProviderCall = providerCode.GenerateUseProvider(Options.ConnectionString);
usings.AddRange(useProviderCall.GetRequiredUsings());

this.Write(" => optionsBuilder");
this.Write(this.ToStringHelper.ToStringWithCulture(code.Fragment(providerCode.GenerateUseProvider(Options.ConnectionString), indent: 3)));
this.Write(this.ToStringHelper.ToStringWithCulture(code.Fragment(useProviderCall, indent: 3)));
this.Write(";\r\n\r\n");

}
Expand Down Expand Up @@ -617,7 +620,7 @@ public class CSharpDbContextGeneratorBase
/// <summary>
/// The string builder that generation-time code is using to assemble generated output
/// </summary>
protected System.Text.StringBuilder GenerationEnvironment
public System.Text.StringBuilder GenerationEnvironment
{
get
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,11 @@ public partial class <#= Options.ContextName #> : DbContext
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
<#
}

var useProviderCall = providerCode.GenerateUseProvider(Options.ConnectionString);
usings.AddRange(useProviderCall.GetRequiredUsings());
#>
=> optionsBuilder<#= code.Fragment(providerCode.GenerateUseProvider(Options.ConnectionString), indent: 3) #>;
=> optionsBuilder<#= code.Fragment(useProviderCall, indent: 3) #>;

<#
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Extensions
{
public class MethodCallCodeFragmentExtensionsTest
{
[ConditionalFact]
public void GetRequiredUsings_works()
{
var methodCall = new MethodCallCodeFragment(
typeof(Namespace1.TestExtensions1)
.GetRuntimeMethod(
nameof(Namespace1.TestExtensions1.Extension1),
new[]
{
typeof(MethodCallCodeFragmentExtensionsTest),
typeof(Action<MethodCallCodeFragmentExtensionsTest>)
}),
new NestedClosureCodeFragment(
"x",
new MethodCallCodeFragment(
typeof(Namespace2.TestExtensions2)
.GetRuntimeMethod(
nameof(Namespace2.TestExtensions2.Extension2),
new[]
{
typeof(MethodCallCodeFragmentExtensionsTest),
typeof(Namespace3.TestArgument)
}),
new Namespace3.TestArgument())));


var usings = methodCall.GetRequiredUsings();

Assert.Equal(
new[]
{
"Microsoft.EntityFrameworkCore.Extensions.Namespace1",
"Microsoft.EntityFrameworkCore.Extensions.Namespace2",
"Microsoft.EntityFrameworkCore.Extensions.Namespace3"
},
usings);
}
}

namespace Namespace1
{
internal static class TestExtensions1
{
public static void Extension1(
this MethodCallCodeFragmentExtensionsTest extendedObject,
Action<MethodCallCodeFragmentExtensionsTest> closure)
=> throw new NotImplementedException();
}
}

namespace Namespace2
{
internal static class TestExtensions2
{
public static void Extension2(
this MethodCallCodeFragmentExtensionsTest extendedObject,
Namespace3.TestArgument argument)
=> throw new NotImplementedException();
}
}

namespace Namespace3
{
internal class TestArgument
{
}
}
}