小编Iva*_*tar的帖子

PHP延迟加载对象和依赖注入

我最近开始阅读有关依赖注入的内容,它让我重新思考了我的一些设计.

我遇到的问题是:让我说我有两个班:汽车和乘客; 对于这两个类,我有一些数据映射器来处理数据库:CarDataMapper和PassengerDataMapper

我希望能够在代码中执行以下操作:

$car = CarDataMapper->getCarById(23); // returns the car object
foreach($car->getPassengers() as $passenger){ // returns all passengers of that car
    $passenger->doSomething();
}
Run Code Online (Sandbox Code Playgroud)

在我对DI有所了解之前,我会像这样构建我的类:

class Car {
    private $_id;
    private $_passengers = null;

    public function getPassengers(){
        if($this->_passengers === null){
            $passengerDataMapper = new PassengerDataMapper;
            $passengers = $passengerDataMapper->getPassengersByCarId($this->getId());
            $this->setPassengers($passengers);
        }
        return $this->_passengers;  
    }

}
Run Code Online (Sandbox Code Playgroud)

我也会在Passenger-> getCar()方法中使用类似的代码来获取乘客所在的汽车.

我现在明白,这会在Car和Passenger对象以及数据映射器对象之间创建依赖关系(好吧,我之前也理解它,但我不知道这是"错误的").

虽然想到了解决这两个选项的解决方案,但我真的不喜欢它们中的任何一个:

1:做这样的事情:

$car = $carDataMapper->getCarById(23);
$passengers = $passengerDataMapper->getPassengersByCarId($car->getId());
$car->setPassengers($passengers);

foreach($car->getPassengers() as $passenger){
    $passenger->doSomething();
}
Run Code Online (Sandbox Code Playgroud)

但是如果乘客有需要注入的对象怎么办呢?如果嵌套进入十到二十级呢?我最终会在我的应用程序开始时实例化几乎所有对象,而这会反过来查询整个数据库.处理.如果我必须将乘客送到另一个必须对乘客拥有的物体做某事的物体,我也不想立即实例化这些物体.

2:将数据映射器注入汽车和乘客对象,并具有以下内容:

class Car {
    private $_id;
    private $_passengers = …
Run Code Online (Sandbox Code Playgroud)

php dependency-injection data-access lazy-loading

18
推荐指数
2
解决办法
9914
查看次数

Unity PerThreadLifetimeManager和任务

我使用EntityFramework和实施了一堆后台作业类的通用存储库和单元的工作模式.使用Unity DI创建作业类,以便可以向它们注入依赖项,这些依赖项主要是存储库和UnitOfWork对象.存储库和工作单元应共享EF DbContext.

一个常见的工作看起来像这样:

public class CommonJob : IJob, IDisposable
{        
    private IRepo<SomeEntity> _repo;
    private IUnitOfWork _uow;

    public CommonJob(IRepo<SomeEntity> repo, IUnitOfWork uow)
    {
        _repo = repo;
        _uow = uow;
    }

    public void RunJob()
    {
        // do stuff here
    }

    public void Dispose()
    {
        _uow.Commit();
        _uow.Dispose();
    }
}
Run Code Online (Sandbox Code Playgroud)

所有工作都在新任务中运行,就像这样

Task.Factory.StartNew(() => {
    // container is UnityContainer
    var job = container.Resolve<CommonJob>();
    job.RunJob();
    job.Dispose();
});
Run Code Online (Sandbox Code Playgroud)

我已经使用Unity注册了工作单元和存储库PerThreadLifetimeManager,认为这样可以在一个任务(以及一个作业对象)的上下文中共享已注册的实例,但不能在外部.

我遇到的问题是,有时工作会注入被处理的对象,这显然不是很好.我一直在阅读Task.Factory.StartNew()并不总是使用新线程.这是否意味着PerThreadLifetimeManager将在任务之间共享对象?如果这是真的,有没有另一种方法来统一管理对象生命周期,这将允许每个任务孤立地工作,无论它运行的线程是什么?

编辑:

虽然下面选择的答案将实现相同的目的,但我最终使用HierarchicalLifetimeManager和子容器来实现每个作业的依赖性隔离.

这是一个例子: …

c# dependency-injection .net-4.0 unity-container task-parallel-library

6
推荐指数
1
解决办法
1991
查看次数

Doctrine2 - 使用外键列作为普通字段

有没有办法在教义中拥有这样的东西:

class Entity {

    /**
     * @Column(name="related_entity_id")
     */
    private $relatedEntityId;

    /**
     * @ManyToOne(targetEntity="RelatedEntitiy")
     * @JoinColumn(name="related_entity_id", referencedColumnName="id")
     */ 
    private $relatedEntity;
}
Run Code Online (Sandbox Code Playgroud)

我想做的事情是这样的:

调用Entity::setRelatedEntityId($someId),并持久化实体,并通过调用Entity::getRelatedEntity()让实体返回相关实体。

相关实体是从严格限制的表中选择的,它永远不会在运行时动态增长,因此相关实体 id 的数量是有限的。

在创建新实体时,我想设置相关实体​​ id,但不必从数据库中获取整个相关实体。

就我可以测试这一点而言,它不起作用,因为如果我设置了 relatedEntityId 而不是 relatedEntity,Doctrine 会自动将 related_entity_id 列设置为 null,因为基本上没有建立任何关系。

我也试过做这样的事情:

删除 relatedEntityId 属性,并使用

Entity::setRelatedEntity(new RelatedEntity($relEntId))
Run Code Online (Sandbox Code Playgroud)

RelatedEntity 的构造函数将设置 id,但不会设置其他值。我不想保留相关实体(它的值已经在数据库中为给定的 $relEntId 设置),但这次 Doctrine 在刷新时发出错误信号,因为它有一个非持久化的实体。

基本上,我想要做的是创建一个关系,除了相关实体的 Id 之外什么都不知道。如果有其他方法可以做到这一点,请分享。

提前致谢

编辑:

我找到了解决方法。由于相关实体将是一组有限的不可变对象,我已经完成了以下操作:

  1. 使用 entityManager 查找所有相关实体;
  2. 将列表注入将创建新实体的对象
  3. 创建新实体时,从列表中选择一个相关实体作为其相关实体

我会把这个问题留待一两天,以防万一有人想出更好的办法。

php orm foreign-key-relationship doctrine-orm

4
推荐指数
1
解决办法
2428
查看次数

从Azure blob存储流式传输视频

.mp4在Azure blob存储中存储视频以显示在Azure上托管的网站时遇到问题.视频类型设置为video/mp4,存储帐户不公开,但它链接到Web角色,我使用这段代码更新了版本:

var credentials = new StorageCredentials("myaccountname", "mysecretkey"); 
var account = new CloudStorageAccount(credentials, true); 
var client = account.CreateCloudBlobClient(); 
var properties = client.GetServiceProperties(); 
properties.DefaultServiceVersion = "2012-02-12"; 
client.SetServiceProperties(properties); 
Run Code Online (Sandbox Code Playgroud)

我没有使用任何视频播放器,只使用HTML5视频标签.我也不需要任何花哨的东西,我只想播放视频.

查看Chrome开发工具中的网络标签,GET获取视频的请求有两个条目.第一个是状态,(pending)下一个是(canceled).

我还给了一个链接到网站内容文件夹中的视频.这个也开始,pending但解决了一个204 Partial Content,视频播放就好了.

我没有看到的东西,任何帮助和指针都表示赞赏.

video azure video-streaming azure-storage

4
推荐指数
1
解决办法
5055
查看次数