PDA

View Full Version : تزریق وابستگی به کمک StructureMap



7asemoon
شنبه 05 تیر 1395, 19:19 عصر
من مقالات زیادی خوندم در مورد تزریق وابستگی و ioc container ها و هرچیزی که در این زمینه فکر کنید
تمامی مقالات این سایت (http://dotnettips.info)رو هم مطالعه کردم
اما متاسفانه چیزی خاصی از کد فوق متوجه نشدم
از دوستان تقاضا دارم با توجه به اینکه قطعا سوال خیلی از افراد مثل من هم هست توضیح مبسوطی در مورد کدهای فوق داده شود

public class ProjectObjectFactory
{
#region Fields
private static readonly Lazy<Container> ContainerBuilder =
new Lazy<Container>(DefaultContainer, LazyThreadSafetyMode.ExecutionAndPublication);
#endregion

#region Container
public static IContainer Container => ContainerBuilder.Value;

#endregion

#region DefaultContainer
private static Container DefaultContainer()
{
var container = new Container(ioc =>
{
ioc.For<Microsoft.AspNet.SignalR.IDependencyResolver>()
.Singleton()
.Add<StructureMapSignalRDependencyResolver>();

ioc.For<IIdentity>()
.Use(
() =>
(HttpContext.Current != null && HttpContext.Current.User != null)
? HttpContext.Current.User.Identity
: null);

ioc.For<IUnitOfWork>()
.HybridHttpOrThreadLocalScoped()
.Use<ApplicationDbContext>();

ioc.For<HttpContextBase>().Use(() => new HttpContextWrapper(HttpContext.Current));
ioc.For<HttpServerUtilityBase>().Use(() => new HttpServerUtilityWrapper(HttpContext.Current.Serve r));
ioc.For<HttpRequestBase>().Use(ctx => ctx.GetInstance<HttpContextBase>().Request);

ioc.For<ISessionProvider>().Use<SessionProvider>();
ioc.For<IRemotingFormatter>().Use(a => new BinaryFormatter());
ioc.For<ITempDataProvider>().Use<CookieTempDataProvider>();

ioc.AddRegistry<AspNetIdentityRegistery>();
ioc.AddRegistry<TaskRegistry>();
ioc.AddRegistry<AutoMapperRegistery>();
ioc.AddRegistry<ServiceLayerRegistery>();

ioc.Scan(scanner => scanner.WithDefaultConventions());
ioc.Policies.SetAllProperties(y => y.OfType<HttpContextBase>());
});
ConfigureAutoMapper(container);
return container;
}
#endregion

#region ConfigureAutoMapper
private static void ConfigureAutoMapper(IContainer container)
{
var configuration = container.TryGetInstance<IConfiguration>();
if (configuration == null) return;
//saying AutoMapper how to resolve services
configuration.ConstructServicesUsing(container.Get Instance);
foreach (var profile in container.GetAllInstances<Profile>())
{
configuration.AddProfile(profile);
}
}
#endregion
}

hakim22
شنبه 05 تیر 1395, 22:44 عصر
به طور کلی کار یک IoC Container این است که کلاسهای مورد نیاز پروژه (وابستگی ها) را به نمونه سازی کند (تزریق کند) .

روش معمول این است که برای کلاسهایی که لازم است بعدا تزریق شود ابتدا یک اینترفیس تعریف شود. بعد در متد اصلی IoC Conatiner باید به روشی اعلام کنید که برای هر اینترفیس باید از کدام کلاس نمونه سازی شود.

مثل :


ioc.For<ISessionProvider>().Use<SessionProvider>() ;


همه ی IoC Container ها ابزاری دارند که نوع تزریق را مشخص می کند. مثلا اگر نوع تزریق به صورت Singleton باشد کلاس مورد نظر با استفاده از معماری Singleton بازسازی میشود. یعنی فقط یکبار نمونه سازی از آن صورت میگیرد و برای هر بار درخواست جدید همان کلاس نمونه سازی شده ی قبلی تحویل داده میشود (چیزی شبیه متغیر های استاتیک)

مثل :


ioc.For<Microsoft.AspNet.SignalR.IDependencyResolv er>()
.Singleton()
.Add<StructureMapSignalRDependencyResolver>();


همینطور همه ی Ioc Container ها معمولی روشی برای مقادیر پیشفرض دارند. به این معنی که شما به Ioc Container اعلام می کنید که هر برای اینترفیسی مشخصا یک کلاس معرفی نشده بود با استفاده از پیشفرض های خودش آن را پیدا کند و بسازد .


ioc.Scan(scanner => scanner.WithDefaultConventions());


پیشفرض معمول این است که برای هر اینترفیسی به دنبال کلاس هم نامش میرود . (فقط حرف I را از اول نام بر میدارد)

7asemoon
یک شنبه 06 تیر 1395, 09:48 صبح
خیلی خلاصه و مفید بود
اگر براتون مقدور هست وطایف قسمت های مختلف تکه کدی رو که گذاشتم توضیح بدین