我最近开始阅读有关依赖注入的内容,它让我重新思考了我的一些设计.
我遇到的问题是:让我说我有两个班:汽车和乘客; 对于这两个类,我有一些数据映射器来处理数据库: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) 我使用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
有没有办法在教义中拥有这样的东西:
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 之外什么都不知道。如果有其他方法可以做到这一点,请分享。
提前致谢
编辑:
我找到了解决方法。由于相关实体将是一组有限的不可变对象,我已经完成了以下操作:
我会把这个问题留待一两天,以防万一有人想出更好的办法。
我.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,视频播放就好了.
我没有看到的东西,任何帮助和指针都表示赞赏.
php ×2
.net-4.0 ×1
azure ×1
c# ×1
data-access ×1
doctrine-orm ×1
lazy-loading ×1
orm ×1
video ×1