<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>SmartSql on Xu ZhiYi</title><link>https://niuniu.space/tags/smartsql/</link><description>Recent content in SmartSql on Xu ZhiYi</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 17 Jun 2025 20:09:57 +0800</lastBuildDate><atom:link href="https://niuniu.space/tags/smartsql/index.xml" rel="self" type="application/rss+xml"/><item><title>SmartSql 多数据库场景下简化 Repository 命名与准确加载 XML SQL 的扩展方法</title><link>https://niuniu.space/posts/smartsql-fullnamescoperesolver-extension/</link><pubDate>Tue, 17 Jun 2025 20:09:57 +0800</pubDate><guid>https://niuniu.space/posts/smartsql-fullnamescoperesolver-extension/</guid><description>&lt;h1 id="smartsql-多数据库场景下简化-repository-命名与准确加载-xml-sql-的扩展方法">
 SmartSql 多数据库场景下简化 Repository 命名与准确加载 XML SQL 的扩展方法
 &lt;a class="heading-link" href="#smartsql-%e5%a4%9a%e6%95%b0%e6%8d%ae%e5%ba%93%e5%9c%ba%e6%99%af%e4%b8%8b%e7%ae%80%e5%8c%96-repository-%e5%91%bd%e5%90%8d%e4%b8%8e%e5%87%86%e7%a1%ae%e5%8a%a0%e8%bd%bd-xml-sql-%e7%9a%84%e6%89%a9%e5%b1%95%e6%96%b9%e6%b3%95">
 &lt;i class="fa-solid fa-link" aria-hidden="true" title="Link to heading">&lt;/i>
 &lt;span class="sr-only">Link to heading&lt;/span>
 &lt;/a>
&lt;/h1>
&lt;p>在多数据库项目中，我们通常会使用多个 SmartSql 实例。每个实例又管理着众多对应数据表的 Repository。&lt;/p>
&lt;p>默认的 &lt;code>AddRepositoryFromAssembly()&lt;/code> 方法加载 Repository 时，仅能通过类名定位对应 Scope 的 XML 文件。这导致了一个问题：为了区分不同数据库表对应的 Repository 类，我们不得不使用冗长的类名，严重影响了开发体验。&lt;/p>
&lt;p>为此，我编写了一个自定义扩展方法作为替代方案。该方法的核心是：通过反射获取 Repository 类的完整名称 (FullName)。由于 SmartSql 的 Scope 部分不支持点号 (&lt;code>.&lt;/code>)，需要将 FullName 中的点号替换为下划线 (&lt;code>_&lt;/code>)。最后，使用转换后的名称去加载对应 Scope 的 XML 文件。&lt;/p>
&lt;p>这种方式的优势在于：位于不同类库中的 Repository，现在可以使用相同或更简短的类名了。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-C#" data-lang="C#">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">static&lt;/span> SmartSqlDIBuilder AddRepositoryFromAssemblyByFullName(&lt;span style="color:#66d9ef">this&lt;/span> SmartSqlDIBuilder builder, Action&amp;lt;AssemblyAutoRegisterOptions&amp;gt; setupOptions)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> builder.AddRepositoryFactory();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> options = &lt;span style="color:#66d9ef">new&lt;/span> AssemblyAutoRegisterOptions
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Filter = type =&amp;gt; type.IsInterface
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> };
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> setupOptions(options);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ScopeTemplateParser templateParser = &lt;span style="color:#66d9ef">new&lt;/span> ScopeTemplateParser(options.ScopeTemplate);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> allTypes = TypeScan.Scan(options);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">foreach&lt;/span> (&lt;span style="color:#66d9ef">var&lt;/span> type &lt;span style="color:#66d9ef">in&lt;/span> allTypes)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> builder.Services.AddSingleton(type, sp =&amp;gt;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> sqlMapper = &lt;span style="color:#66d9ef">string&lt;/span>.IsNullOrEmpty(options.SmartSqlAlias)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> ? sp.EnsureSmartSql().SqlMapper
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> : sp.EnsureSmartSql(options.SmartSqlAlias).SqlMapper;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> factory = sp.GetRequiredService&amp;lt;IRepositoryFactory&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> scope = type.FullName?.Replace(&lt;span style="color:#e6db74">&amp;#34;.&amp;#34;&lt;/span>, &lt;span style="color:#e6db74">&amp;#34;_&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">var&lt;/span> instance = factory.CreateInstance(type, sqlMapper, scope);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">if&lt;/span> (instance.IsDyRepository())
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> sqlMapper.SmartSqlConfig.CacheManager.Reset();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> instance;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> });
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">return&lt;/span> builder;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item></channel></rss>