懒收集加载 - 如何让项目? [英] Lazy Loading of Collection - how to get the items?

查看:80
本文介绍了懒收集加载 - 如何让项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的类,它是旨在成为一个简单的POCO - 它只是保存数据。有一个例外:它包含集合票据。我想延迟加载此集合,这样我就不必获取的注意事项是不需要他们的页面。存根这个是这样的:

I have a simply Class that is intended to be a simple POCO - it just holds data. With one exception: It contains a Collection of Notes. I want to lazy-load this collection so that I don't have to fetch the Notes on Pages that don't need them. The stub for this is this:

public class MyDTOClass 
{
    private ICollection<Note> _notes = null;

    public ICollection<Note> Notes
    {
        get
        {
            if(_notes == null)
            {
                // Get an INoteRepository and initialize the collection
            }
            return _notes;
        }
    }
}

现在,我不知道如何从这里出发。这是一个ASP.net MVC应用程序,我使用依赖注入来注入IRepositories在需要它们,例如我的控制器类。但由于该类这里应该是一个非常简单的DTO,我不愿意到INoteRepository注入其中,还因为调用者不应该担心或关心的事实,这是懒加载。

Now, I'm wondering how to proceed from here. It's an ASP.net MVC application and I use Dependency Injection to inject the IRepositories in classes that need them, for example my controllers. But as this class here is supposed to be a really simple DTO, I'm reluctant to inject an INoteRepository into it, also because the caller shouldn't worry or care about the fact that this is lazy-loaded.

所以,我想有另一班在我的模型,该模型拥有INoteRepository的。

So I'm thinking of having another Class in my Model that holds a INoteRepository.

public class MyDataAccessClass
{
    private INoteRepository _noteRepo;

    // Inject is part of Ninject and makes sure I pass the correct
    // INoteRepository automatically
    [Inject]
    public MyDataAccessClass(INoteRepository noteRepository)
    {
        _noteRepo = noteRepository;
    }

    public IEnumerable<Note> GetNotes(int projectId)
    {
        return _noteRepo.GetNotes(projectId);
    }
}

本会的工作,当然,但我不知道这是否是正确的架构?我夫妇简单DTOClass到另一个数据访问类,还可能到我的DI机制(因为我需要在Notes的吸气创建数据访问类的实例)。

This would work of course, but I wonder if this is the correct architecture? I couple the simple DTOClass to another Data Access class and possibly also to my DI mechanism (as I need to create an Instance of the Data Access class in the getter of Notes).

你会做不同的看法?有没有更好的方式来做到这一点,一点也保持我已经使用Ninject?

Would you do it differently? Is there a better way to do this, also keeping in mind I already use Ninject?

我猜测,这是不是一个POCO或DTO了,因为它现在包含的逻辑,不过没关系。我想它的显示的像一个POCO外来电,所以我想在这个或其它类有一个属性注意事项,而不是像GetNotesForProject的方法。

I'm guessing that this is not a POCO or DTO anymore as it now contains logic, but that's okay. I want it to appear like a POCO to outside caller so I like to have a Property "Notes" rather than methods like "GetNotesForProject" on this or other classes.

我目前的解决方案是十分可怕的,因为我需要从我的MvcApplication得到Ninject内核并用它来旋转起来的ProjectDataProvider类,它需要一个INoteRepository在它的构造函数,以避免把INoteRepository地方在我的DTO 一流的:

My current solution is really ugly, as I need to get the Ninject Kernel from my MvcApplication and use it to spin up the ProjectDataProvider class which takes an INoteRepository in it's constructor, to avoid having to put the INoteRepository somewhere in my "DTO"-Class:

public ICollection<Note> Notes
{
    get
    {
        if(_notes == null)
        {
            var app = HttpContext.Current.ApplicationInstance as MvcApplication;
            if (app == null)
             throw new InvalidOperationException("Application couldn't be found");
            var pdp = app.Kernel.Get<ProjectDataProvider>();
            _notes = new List<Note>(pdp.GetNotes(Id));
        }
        return _notes;
    }
}

编辑:打开赏金。让我们忽略POCO和DTO的术语,我将重构相应。因此,这大概是:?应该如何延迟加载code看看在这种情况下,并可以/我应该避免将INoteRepository到MyDTOClass

Opened a bounty. Let's ignore the terminology of "POCO" and "DTO", I'll refactor accordingly. So this is about: How should the Lazy-Loading code look in such a situation, and can/should I avoid passing INoteRepository into the MyDTOClass?

推荐答案

您DTO并不需要了解的库本身。它所需要的是一个委托,可以为它提供了纸币的价值。

Your DTO doesn't need to know about the repository itself. All it needs is a delegate that can provide it with the value for notes.

怎么是这样的:

public class MyDTOClass
{
    private ICollection<Note> _notes = null;

    public ICollection<Note> Notes
    {
        get
        {
            if (_notes == null)
            {
                if (notesValueProvider == null)
                    throw new InvalidOperationException("ValueProvider for notes is invalid");
                _notes = notesValueProvider();
            }
            return _notes;
        }
    }

    private Func<ICollection<Note>> notesValueProvider = null;

    public MyDTOClass(Func<ICollection<Note>> valueProvider)
    {
        notesValueProvider = valueProvider;
    }
}

自定义,你的资料库应该为你提供的DTO的实例,我们应该能够传递值提供委托像这样:

Since by definition, your repository is supposed to provide you with an instance of the DTO, we should be able to pass in the value provider delegate like so:

public class Repository
{
    public MyDTOClass GetData()
    {
        MyDTOClass dto = new MyDTOClass(FetchNotes);
        return dto;
    }

    public ICollection<Note> FetchNotes()
    {
        return new List<Note>(200);
    }
}

这是否会为你工作?

Will this work for you?

这篇关于懒收集加载 - 如何让项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆