我正在开发OO PHP中的社交网络类型项目,我不想使用现有的框架.这个项目的主要目的是帮助我了解更多的东西.
这个问题更多的是关于依赖注入.
假设我有这些课程:
核心类 - 在app
配置类中执行操作的一些核心方法- 加载站点配置
数据库类 - 连接到mysql并执行所有数据库相关的东西
记录器类 - 用于记录错误和调试信息验证
码类 - 用于表单
会话类上的验证码 - 启动会话启动并添加,删除,获取要在应用程序
缓存类中使用的会话变量- 类似于会话类但对于缓存项(文件缓存,内存缓存,apc缓存.我甚至可能有一天将我的会话内容添加到此类中所有这些缓存都可以使用相同类型的方法)
上面的所有类很可能会在我的应用程序中的每个页面加载时使用(我可能会错过更多将在稍后添加的类)
现在除了需要注入大多数其他类的上述类之外,我还会有更多的类.我将有一个名为模块的部分,它将具有类似......的东西
帐户类 - 创建新用户,对用户进行身份验证,将用户登录和导出应用程序,更新用户设置等等.
用户类 - 显示用户个人资料,显示用户在线,新用户,显示网站
论坛类用户的所有内容- 将用于论坛部分
博客课程 - 用于博客部分
照片课程 - 所有照片相关内容
评论类 - 处理评论用于照片和个人资料
对于网站的不同部分,将会有更多这类类型.
上面列出的第二组类很可能需要将第一组中的大多数类注入其中.
那么我应该使用注册表来存储第一组类中的对象,并将注册表注入第二组类中的所有类对象?
或者我应该使用构造函数来加载它们?在这个例子中,有7个对象可以注入到其他类中,这似乎很多.我错了吗?
---编辑---
我知道单身模式,但我不认为这是我最好的选择
---编辑2 ---
正如有些人提到的,需要传入多达7个对象似乎很多,这就是为什么我在寻找建议.幸运的是,这个项目处于起步阶段,所以现在是改变结构的时候了.
一个例子是我论坛部分的一个类.论坛类需要访问会话数据,可能的缓存数据,配置对象,数据库对象.我错了吗?
我目前正在使用服务定位器重构基于Zend Framework的PHP库(构造函数)依赖注入(DI).我觉得它改进了我的代码很多,但我不确定是否应该注入所有依赖项.对于使用很多且非特定的依赖项,服务定位器似乎更容易.我有以下依赖项,我仍然使用服务定位器访问:
如果我注入了这些依赖项,它们会使我的构造函数混乱并分散特定的依赖关系.为了测试,我可以在运行测试之前在我的服务定位器中设置这些依赖项.我的实用主义者说我做得很好,但纯粹主义者说我应该一直用DI.
你会推荐DI用于这些类型的物体吗?
我正在开发一个 MVC 应用程序,我正在使用 Unity 进行 IoC。我的应用程序基本上由 UI 层、服务层和存储库层组成。
我的典型控制器是:
public class TestController : Controller
{
private ITestService testServ;
public TestController(ITestService _testServ)
{
testServ= _testServ;
}
public ActionResult Index()
{
testServ.DoSomething();
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
没有什么异常,我的每个控制器都注入了一个服务对象。我的服务层对象执行复杂的业务规则,聚合来自许多不同存储库的信息。通过使用 IoC,我发现我的构造函数看起来过于复杂,但由于该服务需要访问许多存储库,我看不到任何解决此问题的方法。
我的服务层中的典型类如下所示:
public class TestService : ITestService
{
private ITransactionRepository transRepo;
private IAccountRepository accountRepo;
private ISystemsRepository sysRepo;
private IScheduleRepository schRepo;
private IProfileRepository profileRepo;
public TestService(ITransactionRepository _transRepo;
IAccountRepository _accountRepo;
ISystemsRepository _sysRepo;
IScheduleRepository _schRepo;
IProfileRepository _profileRepo)
{
transRepo = _transRepo;
accountRepo = _accountRepo;
sysRepo = _sysRepo;
schRepo …Run Code Online (Sandbox Code Playgroud) 有人可以给我一个隐藏依赖的例子.我用谷歌搜索了它,发现了这样的结果:
"可见依赖项是开发人员可以从类的接口看到的依赖项.如果从类的接口中看不到依赖项,则它是隐藏的依赖项."
(来源 - http://tutorials.jenkov.com/ood/understanding-dependencies.html#visiblehidden)
但我还是不太明白.
是否在函数内部发生依赖,而不是在类的开头发生声明的变量?或者,当您只是创建除接口中声明的签名方法之外的函数时?
问题提到了这一切。
在春季启动中,我能够使用AutoWired注释自动将依赖项注入控制器。
class SomeController extends Controller {
@AutoWired
private SomeDependency someDependency;
}
Run Code Online (Sandbox Code Playgroud)
对于asp.net-core-mvc,我很好奇它是否具有此批注,当前的实现方式是将其作为参数添加到构造函数中
[Route("api/[controller]")]
public class SomeController : Controller
{
private SomeContext _someContext;
public SomeController(SomeContext someContext)
{
_someContext = someContext;
}
}
Run Code Online (Sandbox Code Playgroud) 看看我的Controller(我正在使用依赖注入来管理依赖项):
public RoleController(IRoleRepository roleRepository, ISiteRepository siteRepository, IUserRepository userRepository, IDbContext dbContext)
{
_roleRepository = roleRepository;
_siteRepository = siteRepository;
_userRepository = userRepository;
_dbContext = dbContext;
}
Run Code Online (Sandbox Code Playgroud)
拥有许多依赖项的类是代码味道?对?
但是,在我的示例中,我需要关联Users并Sites在a中Role,然后我需要这些依赖关系来执行此关联.
在邮件列表上的一些人我被告知有太多的依赖关系表明某些事情可能是错误的.但我没有别的办法.我分开了我的责任,在那种情况下有一些我不知道如何对待?有什么不对吗?
更新:
我需要Repositories和DbContext,因为DbContext是我的UnitOfWork,存储库不保存.
此示例是一个简单的CRUD,其中包含一些其他功能,例如视图中的关联和GRID.
更新2:
我正在使用我的UI层是MVC的架构.
.net c# asp.net-mvc domain-driven-design dependency-injection
通常,使用方法实例化类,但没有字段或属性,有很多开销吗?
我正在开发一个大量使用构造函数注入的ASP.NET MVC应用程序,到目前为止,一些控制器最多有10个依赖项.但是由于依赖性很多,我使用了一个IMyAppServiceProvider接口和类,它通过MVC 3中的DependencyResolver提供对所有依赖项的泛型访问.
我删除了所有特定于应用程序的代码并使用我的基本设置创建了一个Gist(这不包括下面提到的BaseController设置).
我还创建了一个接受的BaseController类IMyAppServiceProvider.所有控制器都继承自此基类.基类获取IMyAppServiceProvider对象并为所有各种服务提供受保护的变量.代码看起来像这样:
public class BaseController
{
protected IService1 _service1;
protected IService2 _service2;
protected IService3 _service3;
// ...
public BaseController(IMyAppServiceProvider serviceProvider)
{
_service1 = serviceProvider.GetService<IService1>;
_service2 = serviceProvider.GetService<IService2>;
_service3 = serviceProvider.GetService<IService3>;
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
这使得控制器的代码"干净利落".没有私有/受保护的变量,构造函数中没有赋值,服务由基类保护变量引用. 但是,每个请求都将实例化我的应用程序使用的每个服务,无论特定控制器是否使用所有这些服务.
我的服务很简单,只包含一些业务逻辑和数据库交互的方法调用.他们是无国籍人,没有阶级领域或财产.因此,实例化应该很快,但我想知道这是否是最佳实践(我知道这是一个加载的术语).
最好的做法是在域模型的边缘解析和注入具体类型,然后通过域下载这些类型?例如,让容器将具体类型注入Web应用程序中的MVC控制器构造函数或基于服务的应用程序中的服务端点?
我对容器对象图形连线的理解有点松懈.
是否适合在域中执行等效的Container.Resolve()?
我正在使用ASP.NET MVC3解决方案,该解决方案使用依赖注入与autofac.我们的控制器是由autofac正确创建的,所有必需的对象都被正确传入.这些对象通常包括将域对象转换为MVC(视图)模型的服务,存储库和映射器.所以控制器构造函数看起来有点像:
public abcController(
ILogger logger,
IabcRepository abcRepository,
IabcService abcService,
IMapper<AbcDomain, AbcViewModel> abcMapper,
...
)
Run Code Online (Sandbox Code Playgroud)
不幸的是,随着时间的推移,这些构造函数参数列表往往会很快增长.我们的一些控制器现在需要60个或更多参数.
我们在这里创造了一些反模式吗?
编辑
我应该提到我们试图遵循薄的控制器模式.此外,大多数参数都是映射器 - 大约66%.控制方法通常非常简单,并遵循以下模式:
或者这种模式:
我有一个类,我注入两个服务依赖项.我正在使用Unity容器.
public interface IOrganizer
{
void Method1();
void Method2();
void Method3();
}
public class Organizer : IOrganizer
{
private IService1 _service1;
private IService2 _service2;
public Organizer(Iservice1 service1, IService2 service2)
{
_service1 = service1;
_service2 = service2;
}
public void Method1()
{
/*makes use of _service1 and _service2 both to serve the purpose*/
}
public void Method2()
{
/*makes use of only _service1 to serve the purpose*/
}
public void Method3()
{
/*makes use of only _service2 to serve the purpose*/ …Run Code Online (Sandbox Code Playgroud) 我只是在编写一个实现ServiceLocator模式的类.
public class ServiceFactory : IServiceFactory
{
private IDictionary<Type, object> instantiatedServices;
public ServiceFactory()
{
instantiatedServices = new Dictionary<Type, object>();
}
public T GetService<T>() where T : class, new()
{
if (this.instantiatedServices.ContainsKey(typeof(T)))
{
return (T)this.instantiatedServices[typeof(T)];
}
else
{
T service = new T();
instantiatedServices.Add(typeof(T), service);
return service;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有几个问题:
1.)我应该从哪里打电话给这个班级?app.xaml.cs做wpf的东西?
2.)我应该注册服务,如果是,我应该在哪里注册?
3.)当我对服务"ICustomerService"进行延迟初始化时,为什么我应该为它创建一个Register(T服务)方法呢?这是双重工作.
4.)我应该去找服务定位器吗?
UPDATE
目前我觉得我必须为我个人目的强奸DI工具=>
App.xaml.cs =>这里我创建MainWindow并将其datacontext设置为MainViewModel.cs
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
var mainVM = new MainViewModel();
var mainWindow = new …Run Code Online (Sandbox Code Playgroud) 我正在努力理解StructureMap的部分用法.特别是,在文档中有一个关于常见反模式的声明,仅使用StructureMap作为服务定位器而不是构造函数注入(直接来自Structuremap文档的代码示例):
public ShippingScreenPresenter()
{
_service = ObjectFactory.GetInstance<IShippingService>();
_repository = ObjectFactory.GetInstance<IRepository>();
}
Run Code Online (Sandbox Code Playgroud)
代替:
public ShippingScreenPresenter(IShippingService service, IRepository repository)
{
_service = service;
_repository = repository;
}
Run Code Online (Sandbox Code Playgroud)
这对于一个非常短的对象图很好,但是当处理很多级别的对象时,这是否意味着你应该从顶部向下传递更深层对象所需的所有依赖项?当然,这会破坏封装并暴露有关更深层对象实现的过多信息.
假设我正在使用Active Record模式,因此我的记录需要访问数据存储库才能保存和加载自身.如果此记录加载到对象内,该对象是否调用ObjectFactory.CreateInstance()并将其传递给活动记录的构造函数?如果该对象在另一个对象内部怎么办?是否将IRepository作为自己的参数进一步向上?这将向父对象公开我们此时访问数据存储库的事实,外部对象可能不应该知道.
public class OuterClass
{
public OuterClass(IRepository repository)
{
// Why should I know that ThingThatNeedsRecord needs a repository?
// that smells like exposed implementation to me, especially since
// ThingThatNeedsRecord doesn't use the repo itself, but passes it
// to the record.
// Also where do I create repository? Have to instantiate …Run Code Online (Sandbox Code Playgroud) structuremap dependency-injection service-locator constructor-injection
我有一个asp.net-mvc网站,我正在使用ninject for IOC和nhibernate用于我的ORM映射
这是我的IOC绑定代码:
internal class ServiceModule : NinjectModule
{
public override void Load()
{
Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>)).InRequestScope();
}
}
Run Code Online (Sandbox Code Playgroud)
以下是我如何将IOC用于控制器代码的示例:
public FAQController(IIntKeyedRepository<FAQ> faqRepository, IUnitOfWork unitOfWork)
{
_faqRepository = faqRepository;
_unitOfWork = unitOfWork;
}
Run Code Online (Sandbox Code Playgroud)
问题是到目前为止,每个控制器都有一个它指向的表,所以我只需要传递给它的存储库类...
现在,我有许多表和类都只有2个字段:
对于这些类中的每一个,我只是从一个名为的基类继承:
BaseModel
Run Code Online (Sandbox Code Playgroud)
这只是:
public class BaseModel
{
public virtual string Name { get; set; }
public virtual int Id { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我想要一个:
StaticDataController
Run Code Online (Sandbox Code Playgroud)
可以为从BaseModel继承的每个类执行所有CRUD的类(没有额外的字段)
愚蠢的简单方法是这样做:
private readonly IIntKeyedRepository<Object1> _object1Repository;
private readonly IIntKeyedRepository<Object2> _object2Repository;
private readonly IIntKeyedRepository<Object3> _object3Repository;
private readonly IIntKeyedRepository<Object4> _object4Repository; …Run Code Online (Sandbox Code Playgroud) asp.net-mvc dependency-injection ninject repository inversion-of-control
c# ×8
asp.net-mvc ×4
dependencies ×3
.net ×2
php ×2
autofac ×1
autowired ×1
ninject ×1
oop ×1
registry ×1
repository ×1
structuremap ×1