@@ -112,6 +112,9 @@ public virtual class fflib_Application
112
112
return new fflib_SObjectUnitOfWork (objectTypes , dml );
113
113
}
114
114
115
+ /**
116
+ * @param mockUow A mock implementation for the unitOfWork factory
117
+ */
115
118
@TestVisible
116
119
protected virtual void setMock (fflib_ISObjectUnitOfWork mockUow )
117
120
{
@@ -168,6 +171,24 @@ public virtual class fflib_Application
168
171
return serviceImpl .newInstance ();
169
172
}
170
173
174
+ /**
175
+ * Creates or replaces an existing binding for another
176
+ *
177
+ * @param serviceInterfaceType The Interface type to replace its implementation
178
+ * @param replacementImplType The implementation type of the replacement
179
+ */
180
+ public virtual void replaceWith (Type serviceInterfaceType , Type replacementImplType )
181
+ {
182
+ this .m_serviceInterfaceTypeByServiceImplType .put (
183
+ serviceInterfaceType ,
184
+ replacementImplType
185
+ );
186
+ }
187
+
188
+ /**
189
+ * @param serviceInterfaceType The interface type to mock
190
+ * @param serviceImpl The mock implementation
191
+ */
171
192
@TestVisible
172
193
protected virtual void setMock (Type serviceInterfaceType , Object serviceImpl )
173
194
{
@@ -246,6 +267,27 @@ public virtual class fflib_Application
246
267
return newInstance (domainSObjectType ).selectSObjectsById (recordIds );
247
268
}
248
269
270
+ /**
271
+ * Helper method to query the given SObject records
272
+ * Internally creates an instance of the registered Selector and calls its
273
+ * selectSObjectById method.
274
+ * It assumes that all Ids are of the given SObjectType, no additional validation is done.
275
+ *
276
+ * @param recordIds The recordIds to query
277
+ * @param sObjectType The SObjectType of the Ids
278
+ *
279
+ * @return The queried records
280
+ * @exception fflib_Application.DeveloperException is thrown if the Ids set is empty
281
+ */
282
+ public virtual List <SObject > selectById (Set <Id > recordIds , SObjectType sObjectType )
283
+ {
284
+ if (recordIds == null || recordIds .size () == 0 )
285
+ throw new fflib_Application .DeveloperException (' Invalid record Id\' s set' );
286
+
287
+ return newInstance (sObjectType )
288
+ .selectSObjectsById (recordIds );
289
+ }
290
+
249
291
/**
250
292
* Helper method to query related records to those provided, for example
251
293
* if passed a list of Opportunity records and the Account Id field will
@@ -270,19 +312,44 @@ public virtual class fflib_Application
270
312
return selectById (relatedIds );
271
313
}
272
314
315
+ /**
316
+ * Creates or replaces an existing binding for another
317
+ *
318
+ * @param sObjectType The SObjectType of the selector to replace
319
+ * @param replacementImplType The implementation type of the replacement
320
+ */
321
+ public virtual void replaceWith (SObjectType sObjectType , Type replacementImplType )
322
+ {
323
+ this .m_sObjectBySelectorType .put (sObjectType , replacementImplType );
324
+ }
325
+
326
+ /**
327
+ * @param selectorInstance The instance of the mocked selector
328
+ */
273
329
@TestVisible
274
330
protected virtual void setMock (fflib_ISObjectSelector selectorInstance )
275
331
{
276
332
m_sObjectByMockSelector .put (selectorInstance .sObjectType (), selectorInstance );
277
- }
333
+ }
334
+
335
+ /**
336
+ * @param sObjectType The SObjectType of the selector mock,
337
+ * avoids the need to stub the mock to return its SObjectType
338
+ * @param selectorInstance The instance of the mocked selector
339
+ */
340
+ @TestVisible
341
+ protected virtual void setMock (SObjectType sObjectType , fflib_ISObjectSelector selectorInstance )
342
+ {
343
+ this .m_sObjectByMockSelector .put (sObjectType , selectorInstance );
344
+ }
278
345
}
279
346
280
347
/**
281
348
* Class implements a Domain class factory
282
349
**/
283
350
public virtual class DomainFactory implements fflib_IDomainFactory
284
351
{
285
- protected fflib_Application. SelectorFactory m_selectorFactory ;
352
+ protected fflib_ISelectorFactory m_selectorFactory ;
286
353
287
354
protected Map <Object , Type > constructorTypeByObject ;
288
355
@@ -302,10 +369,10 @@ public virtual class fflib_Application
302
369
* @param selectorFactory , e.g. Application.Selector
303
370
* @param constructorTypeByObject Map of Domain classes by ObjectType
304
371
**/
305
- public DomainFactory (fflib_Application. SelectorFactory selectorFactory ,
372
+ public DomainFactory (fflib_ISelectorFactory selectorFactory ,
306
373
Map <Object , Type > constructorTypeByObject )
307
374
{
308
- m_selectorFactory = selectorFactory ;
375
+ this . m_selectorFactory = selectorFactory ;
309
376
this .constructorTypeByObject = constructorTypeByObject ;
310
377
this .mockDomainByObject = new Map <Object , fflib_IDomain >();
311
378
}
@@ -319,10 +386,10 @@ public virtual class fflib_Application
319
386
* @param selectorFactory, e.g. Application.Selector
320
387
* @param sObjectByDomainConstructorType Map of Apex classes by SObjectType
321
388
**/
322
- public DomainFactory (fflib_Application. SelectorFactory selectorFactory ,
389
+ public DomainFactory (fflib_ISelectorFactory selectorFactory ,
323
390
Map <SObjectType , Type > sObjectByDomainConstructorType )
324
391
{
325
- m_selectorFactory = selectorFactory ;
392
+ this . m_selectorFactory = selectorFactory ;
326
393
this .constructorTypeByObject = getConstructorTypeByObject (sObjectByDomainConstructorType );
327
394
this .mockDomainByObject = new Map <Object , fflib_IDomain >();
328
395
}
@@ -338,7 +405,22 @@ public virtual class fflib_Application
338
405
public virtual fflib_IDomain newInstance (Set <Id > recordIds )
339
406
{
340
407
return newInstance (m_selectorFactory .selectById (recordIds ));
408
+ }
341
409
410
+ /**
411
+ * Dynamically constructs an instance of a Domain class for the given record Ids
412
+ * Internally uses the Selector Factory to query the records before passing to a
413
+ * dynamically constructed instance of the application Apex Domain class
414
+ *
415
+ * @param recordIds A list of Id's of the same type
416
+ * @param sObjectType The SObjectType of the given record Ids
417
+ *
418
+ * @return Instance of a Domain containing the queried records
419
+ * @exception Throws an exception via the Selector Factory if the Ids are not all of the same SObjectType
420
+ **/
421
+ public virtual fflib_IDomain newInstance (Set <Id > recordIds , Schema.SObjectType sObjectType )
422
+ {
423
+ return newInstance (m_selectorFactory .selectById (recordIds , sObjectType ), sObjectType );
342
424
}
343
425
344
426
/**
@@ -412,18 +494,60 @@ public virtual class fflib_Application
412
494
);
413
495
}
414
496
497
+ /**
498
+ * Creates or replaces an existing binding for another
499
+ *
500
+ * @param sObjectType The SObjectType of the selector to replace
501
+ * @param replacementImplType The implementation type of the replacement
502
+ */
503
+ public virtual void replaceWith (Schema.SObjectType sObjectType , Type replacementImplType )
504
+ {
505
+ this .constructorTypeByObject .put (
506
+ (Object ) sObjectType ,
507
+ replacementImplType
508
+ );
509
+ }
510
+
511
+ /**
512
+ * @param mockDomain The instance of the Domain mock
513
+ */
415
514
@TestVisible
416
515
protected virtual void setMock (fflib_ISObjectDomain mockDomain )
417
516
{
418
517
mockDomainByObject .put ((Object ) mockDomain .sObjectType (), (fflib_IDomain ) mockDomain );
419
518
}
420
519
520
+ /**
521
+ * @param mockDomain The instance of the Domain mock
522
+ */
421
523
@TestVisible
422
524
protected virtual void setMock (fflib_IDomain mockDomain )
423
525
{
424
526
mockDomainByObject .put (mockDomain .getType (), mockDomain );
425
527
}
426
528
529
+ /**
530
+ * @param sObjectType The SObjectType of the Domain mock,
531
+ * avoids the need to stub the mock to return its SObjectType
532
+ * @param mockDomain The instance of the Domain mock
533
+ */
534
+ @TestVisible
535
+ protected virtual void setMock (Schema.SObjectType sObjectType , fflib_ISObjectDomain mockDomain )
536
+ {
537
+ mockDomainByObject .put ((Object ) sObjectType , mockDomain );
538
+ }
539
+
540
+ /**
541
+ * @param domainType The ObjectType of the Domain mock,
542
+ * avoids the need to stub the mock to return its ObjectType
543
+ * @param mockDomain The instance of the Domain mock
544
+ */
545
+ @TestVisible
546
+ protected virtual void setMock (Object domainType , fflib_IDomain mockDomain )
547
+ {
548
+ mockDomainByObject .put (domainType , mockDomain );
549
+ }
550
+
427
551
protected virtual Map <Object , Type > getConstructorTypeByObject (Map <SObjectType , Type > constructorTypeBySObjectType )
428
552
{
429
553
Map <Object , Type > result = new Map <Object , Type >();
0 commit comments