.NET Core 2.0模块化依赖注入

时间:2018-02-12 16:12:07

标签: c# entity-framework dependency-injection .net-core

我正在尝试构建一个包含Entity Framework及其数据库提供程序等核心和扩展包的库。

我想要做的是当我使用依赖注入注册该库时,我想将特定实现作为参数。

想想EF。为了在EF上使用sql提供程序,我们需要将它作为选项参数传递给SQL提供程序,如下所示。

<div class="pdfContainer">
    <meta charset="UTF-8">
    <link href="http://localhost:8000/css/pdfpreview.css" rel="stylesheet" type="text/css">
    <div class="headerPreview">
        <img src="http://localhost:8000/image/logo.png">
        <div class="soumissionInfoContainer">
            <div>
                <strong>Soumission # </strong>
                <strong>Projet :</strong>
                <strong>Date : </strong>
            </div>
            <div>
                <p> S1-17</p>
                <p>Garage de béton</p>
                <p> 20-02-2017</p>
            </div>
        </div>
        <div class="infoComp">
            <p>2236, rue de l'Ardoise, Jonquière (QC) G8A 0A5</p>
            <p>Saguenay : 418-550-5382 Alma : 418-719-0588</p>
            <p>R.B.Q.: 5670-0578-01</p>
        </div>
        <h2>SOUMISSION</h2>
        <div class="clientInfoContainer">
            <div style="width:70px;"><p style="font-size: 12px;text-align: right">Destinataire: </p>
            </div>
            <div>
                <p>Jean Tremblay</p>
               <p>1010 St Hubert
                    , G7H 2B1</p>
                <p>418 555 5555</p>
            </div>
    </div>
    </div>
<table class="previewTable" id="previewTable">
    <tbody>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
    <tr>
        <th>Quantité</th>
        <th>Description</th>
        <th>Prix</th>
    </tr>
    <tr>
        <td></td>
        <td>
            <textarea id="title1" onchange="setInnerHTML('title1')"
                      style="font-size: 2em; background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%; height: 99px;">Excavation lol</textarea>
        </td>
        <td><textarea id="total1" onchange="setInnerHTML('total1')"
                      style="background: rgba(0,0,0,0); width: 100px; height: 70px">919.51</textarea>
        </td>
    </tr>
    <tr>
        <td></td>
        <td>
            <textarea id="desc1" onchange="setInnerHTML('desc1')" style="resize: horizontal; width: 553px;" rows="5"
                      cols="50" title="">                            this is working</textarea>
        </td>
    </tr>
    </tbody>
</table>
<script>
    function setInnerHTML(id) {
        var area = document.getElementById(id);
        area.innerHTML = area.value;
    }
</script>
<textarea class="totalSoumission" id="totalSoumission" onchange="setInnerHTML('totalSoumission')">TOTAL AVANT TAXES: 919.51 $</textarea>
    <div class="ligne_signature">
        <p>À la signature, ce devis est bon pour travaux et valide 90 jours</p>
    </div>
</div>

我想建立类似的结构。让我们说我的框架将提供电影制片人。它将包含用于框架相关类的services.AddDbContext<ApplicationDbContext>(options => { options.UseSqlServer(Configuration["ConnectionString"]); }); 包和两个名为producer.coreProducer.Extensions.Hollywood的扩展包。

如果我想使用Producer.Extensions.Bollywood提供程序,我需要安装核心程序包和Hollywood扩展程序包。注册时应该看起来像

Hollywood

我甚至找不到能给我指路的关键词。我试图阅读实体框架的源代码,但对我的情况来说太复杂了。

有没有人可以指点我的方向?

提前致谢。

1 个答案:

答案 0 :(得分:3)

我不确定我是否完全理解您的要求,但在.net核心中,DI和扩展是一件容易的事。

让我们在Startup.cs

中说你想要这个
services.AddFilmProducer(options =>
{
   options.UseHollywoodProducer();
});

要实现此功能,请创建库并添加静态扩展类

public static class FilmProducerServiceExtensions
{
    public static IServiceCollection AddFilmProducer(this IServiceCollection services, Action<ProducerOptions> options)
    {
        // Create your delegate
        var producerOptions = new ProducerOptions();
        options(producerOptions);

        // Do additional service initialization
        return services;
    }
}

您的ProducerOptions实现可能看起来像

public class ProducerOptions
{
    public void UseHollywoodProducer() 
    { 
        // Initialize hollywood
    }

    public void UseBollywoodProducer() 
    { 
        // Initialize bollywood
    }
}

如果您希望在服务中使用传递的ProducerOptions,有两种方法可以执行此操作。再次使用依赖注入,或者在扩展方法中使用服务提供者直接访问服务

var serviceProvider = services.BuildServiceProvider()
IYourService service = sp.GetService<IYourService>();

现在你有了原始的使用初始化工作。

希望它有所帮助。

编辑:

澄清。要在服务中注入选项,可以使用

services.Configure(ProducerOptions);
在您的扩展方法中

,并通过

传递给您的服务构造函数
public YourService(IOptions<ProducerOptions>)

然后,您可以根据需要简化或复杂化您的选项。

此类扩展的有用链接可能是.net核心的CORS存储库:https://github.com/aspnet/CORS

评论后编辑:

我想我现在已经得到了它。您希望包扩展并实现特定选项,类似于serilog对不同接收器的作用。一块蛋糕。

废弃ProducerOptions实现。

假设您有一个包含初始空结构(BaseProducer库)和接口

的基础包
public interface IProducerOptions
{
    // base method signatures
}

您的服务扩展程序现在变为

public static class FilmProducerServiceExtensions
{
    public static IServiceCollection AddFilmProducer(this IServiceCollection services, Action<IProducerOptions> options)
    {
        // Do additional service initialization
        return services;
    }
}

现在,您可以使用特定的&#34;好莱坞制作人&#34;创建一个新的包。选项,您想要扩展基本选项集

public static class HollyWoodExtensions
{
    public static void UseHollywoodProducer(this IProducerOptions options)
    {
        // Add implementation
    }
}

根据需要创建尽可能多的包和IProducerOptions扩展,添加的方法将开始出现在您的Startup.cs

services.AddFilmProducer(options =>
{
   options.UseHollywoodProducer();
});